Rip out error codes

As it turns out, they're rather annoying to maintain, and we don't even need
them.  They also clutter the code unnecessarily in their current form.

If it ever comes to having to have them, let's make another version of
error_set(), maybe error_set_with_code(), that makes it possible to also set
an integer within `struct error'.

The only problem with the above solution is when we aggregate errors from
multiple functions (be it by calling one after another, or through nesting of
functions that may return an error).

But let's care about that when the time comes for it.
This commit is contained in:
Přemysl Eric Janouch 2014-07-15 22:54:39 +02:00
parent a2a979ea2e
commit 2921eed702
3 changed files with 36 additions and 124 deletions

View File

@ -505,33 +505,14 @@ str_remove_slice (struct str *self, size_t start, size_t length)
struct error struct error
{ {
size_t domain; ///< The domain of the error
int id; ///< The concrete error ID
char *message; ///< Textual description of the event char *message; ///< Textual description of the event
}; };
static size_t static void
error_resolve_domain (size_t *tag) error_set (struct error **e, const char *message, ...) ATTRIBUTE_PRINTF (2, 3);
{
// This method is fairly sensitive to the order in which resolution
// requests come in, does not provide a good way of decoding the number
// back to a meaningful identifier, and may not play all too well with
// dynamic libraries when a module is e.g. statically linked into multiple
// libraries, but it's fast, simple, and more than enough for our purposes.
static size_t domain_counter;
if (!*tag)
*tag = ++domain_counter;
return *tag;
}
static void static void
error_set (struct error **e, size_t domain, int id, error_set (struct error **e, const char *message, ...)
const char *message, ...) ATTRIBUTE_PRINTF (4, 5);
static void
error_set (struct error **e, size_t domain, int id,
const char *message, ...)
{ {
if (!e) if (!e)
return; return;
@ -544,8 +525,6 @@ error_set (struct error **e, size_t domain, int id,
hard_assert (size >= 0); hard_assert (size >= 0);
struct error *tmp = xmalloc (sizeof *tmp); struct error *tmp = xmalloc (sizeof *tmp);
tmp->domain = domain;
tmp->id = id;
tmp->message = xmalloc (size + 1); tmp->message = xmalloc (size + 1);
va_start (ap, message); va_start (ap, message);
@ -1438,14 +1417,6 @@ resolve_config_filename (const char *filename)
return result; return result;
} }
static size_t io_error_domain_tag;
#define IO_ERROR (error_resolve_domain (&io_error_domain_tag))
enum
{
IO_ERROR_FAILED
};
static bool static bool
ensure_directory_existence (const char *path, struct error **e) ensure_directory_existence (const char *path, struct error **e)
{ {
@ -1455,16 +1426,14 @@ ensure_directory_existence (const char *path, struct error **e)
{ {
if (mkdir (path, S_IRWXU | S_IRWXG | S_IRWXO)) if (mkdir (path, S_IRWXU | S_IRWXG | S_IRWXO))
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, error_set (e, "cannot create directory `%s': %s",
"cannot create directory `%s': %s",
path, strerror (errno)); path, strerror (errno));
return false; return false;
} }
} }
else if (!S_ISDIR (st.st_mode)) else if (!S_ISDIR (st.st_mode))
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, error_set (e, "cannot create directory `%s': %s",
"cannot create directory `%s': %s",
path, "file exists but is not a directory"); path, "file exists but is not a directory");
return false; return false;
} }
@ -1574,14 +1543,6 @@ xssl_get_error (SSL *ssl, int result, const char **error_info)
// --- Regular expressions ----------------------------------------------------- // --- Regular expressions -----------------------------------------------------
static size_t regex_error_domain_tag;
#define REGEX_ERROR (error_resolve_domain (&regex_error_domain_tag))
enum
{
REGEX_ERROR_COMPILATION_FAILED
};
static regex_t * static regex_t *
regex_compile (const char *regex, int flags, struct error **e) regex_compile (const char *regex, int flags, struct error **e)
{ {
@ -1599,8 +1560,7 @@ regex_compile (const char *regex, int flags, struct error **e)
desc.str + desc.len, desc.alloc - desc.len) - 1; desc.str + desc.len, desc.alloc - desc.len) - 1;
free (re); free (re);
error_set (e, REGEX_ERROR, REGEX_ERROR_COMPILATION_FAILED, error_set (e, "%s: %s", "failed to compile regular expression", desc.str);
"%s: %s", "failed to compile regular expression", desc.str);
str_free (&desc); str_free (&desc);
return NULL; return NULL;
} }
@ -1793,14 +1753,6 @@ irc_strcmp (const char *a, const char *b)
// The keys are stripped of surrounding whitespace, the values are not. // The keys are stripped of surrounding whitespace, the values are not.
static size_t config_error_domain_tag;
#define CONFIG_ERROR (error_resolve_domain (&config_error_domain_tag))
enum
{
CONFIG_ERROR_MALFORMED
};
struct config_item struct config_item
{ {
const char *key; const char *key;
@ -1828,8 +1780,8 @@ read_config_file (struct str_map *config, struct error **e)
FILE *fp = fopen (filename, "r"); FILE *fp = fopen (filename, "r");
if (!fp) if (!fp)
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, error_set (e, "could not open `%s' for reading: %s",
"could not open `%s' for reading: %s", filename, strerror (errno)); filename, strerror (errno));
return false; return false;
} }
@ -1851,8 +1803,8 @@ read_config_file (struct str_map *config, struct error **e)
{ {
if (*start) if (*start)
{ {
error_set (e, CONFIG_ERROR, CONFIG_ERROR_MALFORMED, error_set (e, "line %u in config: %s",
"line %u in config: %s", line_no, "malformed input"); line_no, "malformed input");
errors = true; errors = true;
break; break;
} }
@ -1907,8 +1859,8 @@ write_default_config (const char *filename, const char *prolog,
FILE *fp = fopen (path.str, "w"); FILE *fp = fopen (path.str, "w");
if (!fp) if (!fp)
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, error_set (e, "could not open `%s' for writing: %s",
"could not open `%s' for writing: %s", path.str, strerror (errno)); path.str, strerror (errno));
goto error; goto error;
} }
@ -1927,8 +1879,7 @@ write_default_config (const char *filename, const char *prolog,
fclose (fp); fclose (fp);
if (errno) if (errno)
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, error_set (e, "writing to `%s' failed: %s", path.str, strerror (errno));
"writing to `%s' failed: %s", path.str, strerror (errno));
goto error; goto error;
} }

View File

@ -425,15 +425,6 @@ server_context_free (struct server_context *self)
// --- Main program ------------------------------------------------------------ // --- Main program ------------------------------------------------------------
static size_t network_error_domain_tag;
#define NETWORK_ERROR (error_resolve_domain (&network_error_domain_tag))
enum
{
NETWORK_ERROR_INVALID_CONFIGURATION,
NETWORK_ERROR_FAILED
};
static void static void
client_kill (struct client *c, const char *reason) client_kill (struct client *c, const char *reason)
{ {
@ -1140,8 +1131,7 @@ irc_initialize_catalog (struct server_context *ctx, struct error **e)
char *path = resolve_config_filename (catalog); char *path = resolve_config_filename (catalog);
if (!path) if (!path)
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s", error_set (e, "%s: %s", "cannot open file", catalog);
"cannot open file", catalog);
return false; return false;
} }
ctx->catalog = catopen (path, NL_CAT_LOCALE); ctx->catalog = catopen (path, NL_CAT_LOCALE);
@ -1149,7 +1139,7 @@ irc_initialize_catalog (struct server_context *ctx, struct error **e)
if (ctx->catalog == (nl_catd) -1) if (ctx->catalog == (nl_catd) -1)
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s", error_set (e, "%s: %s",
"failed reading the message catalog file", strerror (errno)); "failed reading the message catalog file", strerror (errno));
return false; return false;
} }
@ -1167,8 +1157,7 @@ irc_initialize_motd (struct server_context *ctx, struct error **e)
char *path = resolve_config_filename (motd); char *path = resolve_config_filename (motd);
if (!path) if (!path)
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s", error_set (e, "%s: %s", "cannot open file", motd);
"cannot open file", motd);
return false; return false;
} }
FILE *fp = fopen (path, "r"); FILE *fp = fopen (path, "r");
@ -1176,7 +1165,7 @@ irc_initialize_motd (struct server_context *ctx, struct error **e)
if (!fp) if (!fp)
{ {
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s", error_set (e, "%s: %s",
"failed reading the MOTD file", strerror (errno)); "failed reading the MOTD file", strerror (errno));
return false; return false;
} }
@ -1201,9 +1190,8 @@ irc_initialize_server_name (struct server_context *ctx, struct error **e)
res = irc_validate_hostname (server_name); res = irc_validate_hostname (server_name);
if (res != VALIDATION_OK) if (res != VALIDATION_OK)
{ {
error_set (e, NETWORK_ERROR, NETWORK_ERROR_INVALID_CONFIGURATION, error_set (e, "invalid configuration value for `%s': %s",
"invalid configuration value for `%s': %s", "server_name", "server_name", irc_validate_to_str (res));
irc_validate_to_str (res));
return false; return false;
} }
ctx->server_name = xstrdup (server_name); ctx->server_name = xstrdup (server_name);
@ -1213,14 +1201,14 @@ irc_initialize_server_name (struct server_context *ctx, struct error **e)
char hostname[HOST_NAME_MAX]; char hostname[HOST_NAME_MAX];
if (gethostname (hostname, sizeof hostname)) if (gethostname (hostname, sizeof hostname))
{ {
error_set (e, NETWORK_ERROR, NETWORK_ERROR_INVALID_CONFIGURATION, error_set (e, "%s: %s",
"%s: %s", "getting the hostname failed", strerror (errno)); "getting the hostname failed", strerror (errno));
return false; return false;
} }
res = irc_validate_hostname (hostname); res = irc_validate_hostname (hostname);
if (res != VALIDATION_OK) if (res != VALIDATION_OK)
{ {
error_set (e, NETWORK_ERROR, NETWORK_ERROR_INVALID_CONFIGURATION, error_set (e,
"`%s' is not set and the hostname (`%s') cannot be used: %s", "`%s' is not set and the hostname (`%s') cannot be used: %s",
"server_name", hostname, irc_validate_to_str (res)); "server_name", hostname, irc_validate_to_str (res));
return false; return false;
@ -1246,7 +1234,7 @@ irc_listen (struct server_context *ctx, struct error **e)
int err = getaddrinfo (bind_host, bind_port, &gai_hints, &gai_result); int err = getaddrinfo (bind_host, bind_port, &gai_hints, &gai_result);
if (err) if (err)
{ {
error_set (e, NETWORK_ERROR, NETWORK_ERROR_FAILED, "%s: %s: %s", error_set (e, "%s: %s: %s",
"network setup failed", "getaddrinfo", gai_strerror (err)); "network setup failed", "getaddrinfo", gai_strerror (err));
return false; return false;
} }
@ -1291,8 +1279,7 @@ irc_listen (struct server_context *ctx, struct error **e)
if (!gai_iter) if (!gai_iter)
{ {
error_set (e, NETWORK_ERROR, NETWORK_ERROR_FAILED, error_set (e, "network setup failed");
"network setup failed");
return false; return false;
} }

View File

@ -106,15 +106,6 @@ plugin_data_free (struct plugin_data *self)
str_free (&self->queued_output); str_free (&self->queued_output);
} }
static size_t connect_error_domain_tag;
#define CONNECT_ERROR (error_resolve_domain (&connect_error_domain_tag))
enum
{
CONNECT_ERROR_INVALID_CONFIGURATION,
CONNECT_ERROR_FAILED
};
struct bot_context struct bot_context
{ {
struct str_map config; ///< User configuration struct str_map config; ///< User configuration
@ -306,8 +297,7 @@ error_ssl_2:
error_ssl_1: error_ssl_1:
// XXX: these error strings are really nasty; also there could be // XXX: these error strings are really nasty; also there could be
// multiple errors on the OpenSSL stack. // multiple errors on the OpenSSL stack.
error_set (e, CONNECT_ERROR, CONNECT_ERROR_FAILED, error_set (e, "%s: %s", "could not initialize SSL",
"%s: %s", "could not initialize SSL",
ERR_error_string (ERR_get_error (), NULL)); ERR_error_string (ERR_get_error (), NULL));
return false; return false;
} }
@ -325,7 +315,7 @@ irc_establish_connection (struct bot_context *ctx,
int err = getaddrinfo (host, port, &gai_hints, &gai_result); int err = getaddrinfo (host, port, &gai_hints, &gai_result);
if (err) if (err)
{ {
error_set (e, CONNECT_ERROR, CONNECT_ERROR_FAILED, "%s: %s: %s", error_set (e, "%s: %s: %s",
"connection failed", "getaddrinfo", gai_strerror (err)); "connection failed", "getaddrinfo", gai_strerror (err));
return false; return false;
} }
@ -367,7 +357,7 @@ irc_establish_connection (struct bot_context *ctx,
if (!gai_iter) if (!gai_iter)
{ {
error_set (e, CONNECT_ERROR, CONNECT_ERROR_FAILED, "connection failed"); error_set (e, "connection failed");
return false; return false;
} }
@ -633,16 +623,6 @@ setup_recovery_handler (struct bot_context *ctx)
/// The name of the special IRC command for interprocess communication /// The name of the special IRC command for interprocess communication
static const char *plugin_ipc_command = "ZYKLONB"; static const char *plugin_ipc_command = "ZYKLONB";
static size_t plugin_error_domain_tag;
#define PLUGIN_ERROR (error_resolve_domain (&plugin_error_domain_tag))
enum
{
PLUGIN_ERROR_ALREADY_LOADED,
PLUGIN_ERROR_NOT_LOADED,
PLUGIN_ERROR_LOADING_FAILED
};
static struct plugin_data * static struct plugin_data *
plugin_find_by_pid (struct bot_context *ctx, pid_t pid) plugin_find_by_pid (struct bot_context *ctx, pid_t pid)
{ {
@ -923,29 +903,26 @@ plugin_load (struct bot_context *ctx, const char *name, struct error **e)
const char *plugin_dir = str_map_find (&ctx->config, "plugin_dir"); const char *plugin_dir = str_map_find (&ctx->config, "plugin_dir");
if (!plugin_dir) if (!plugin_dir)
{ {
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_LOADING_FAILED, error_set (e, "plugin directory not set");
"plugin directory not set");
return false; return false;
} }
if (!is_valid_plugin_name (name)) if (!is_valid_plugin_name (name))
{ {
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_LOADING_FAILED, error_set (e, "invalid plugin name");
"invalid plugin name");
return false; return false;
} }
if (str_map_find (&ctx->plugins_by_name, name)) if (str_map_find (&ctx->plugins_by_name, name))
{ {
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_ALREADY_LOADED, error_set (e, "the plugin has already been loaded");
"the plugin has already been loaded");
return false; return false;
} }
int stdin_pipe[2]; int stdin_pipe[2];
if (pipe (stdin_pipe) == -1) if (pipe (stdin_pipe) == -1)
{ {
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_LOADING_FAILED, "%s: %s: %s", error_set (e, "%s: %s: %s",
"failed to load the plugin", "pipe", strerror (errno)); "failed to load the plugin", "pipe", strerror (errno));
goto fail_1; goto fail_1;
} }
@ -953,7 +930,7 @@ plugin_load (struct bot_context *ctx, const char *name, struct error **e)
int stdout_pipe[2]; int stdout_pipe[2];
if (pipe (stdout_pipe) == -1) if (pipe (stdout_pipe) == -1)
{ {
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_LOADING_FAILED, "%s: %s: %s", error_set (e, "%s: %s: %s",
"failed to load the plugin", "pipe", strerror (errno)); "failed to load the plugin", "pipe", strerror (errno));
goto fail_2; goto fail_2;
} }
@ -964,7 +941,7 @@ plugin_load (struct bot_context *ctx, const char *name, struct error **e)
pid_t pid = fork (); pid_t pid = fork ();
if (pid == -1) if (pid == -1)
{ {
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_LOADING_FAILED, "%s: %s: %s", error_set (e, "%s: %s: %s",
"failed to load the plugin", "fork", strerror (errno)); "failed to load the plugin", "fork", strerror (errno));
goto fail_3; goto fail_3;
} }
@ -1034,8 +1011,7 @@ plugin_unload (struct bot_context *ctx, const char *name, struct error **e)
if (!plugin) if (!plugin)
{ {
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_NOT_LOADED, error_set (e, "no such plugin is loaded");
"no such plugin is loaded");
return false; return false;
} }
@ -1551,16 +1527,14 @@ irc_connect (struct bot_context *ctx, struct error **e)
// do we tell our caller that he should not try to reconnect? // do we tell our caller that he should not try to reconnect?
if (!irc_host) if (!irc_host)
{ {
error_set (e, CONNECT_ERROR, CONNECT_ERROR_INVALID_CONFIGURATION, error_set (e, "no hostname specified in configuration");
"no hostname specified in configuration");
return false; return false;
} }
bool use_ssl; bool use_ssl;
if (!set_boolean_if_valid (&use_ssl, ssl_use_str)) if (!set_boolean_if_valid (&use_ssl, ssl_use_str))
{ {
error_set (e, CONNECT_ERROR, CONNECT_ERROR_INVALID_CONFIGURATION, error_set (e, "invalid configuration value for `%s'", "use_ssl");
"invalid configuration value for `%s'", "use_ssl");
return false; return false;
} }