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
{
size_t domain; ///< The domain of the error
int id; ///< The concrete error ID
char *message; ///< Textual description of the event
};
static size_t
error_resolve_domain (size_t *tag)
{
// 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
error_set (struct error **e, const char *message, ...) ATTRIBUTE_PRINTF (2, 3);
static void
error_set (struct error **e, size_t domain, int id,
const char *message, ...) ATTRIBUTE_PRINTF (4, 5);
static void
error_set (struct error **e, size_t domain, int id,
const char *message, ...)
error_set (struct error **e, const char *message, ...)
{
if (!e)
return;
@ -544,8 +525,6 @@ error_set (struct error **e, size_t domain, int id,
hard_assert (size >= 0);
struct error *tmp = xmalloc (sizeof *tmp);
tmp->domain = domain;
tmp->id = id;
tmp->message = xmalloc (size + 1);
va_start (ap, message);
@ -1438,14 +1417,6 @@ resolve_config_filename (const char *filename)
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
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))
{
error_set (e, IO_ERROR, IO_ERROR_FAILED,
"cannot create directory `%s': %s",
error_set (e, "cannot create directory `%s': %s",
path, strerror (errno));
return false;
}
}
else if (!S_ISDIR (st.st_mode))
{
error_set (e, IO_ERROR, IO_ERROR_FAILED,
"cannot create directory `%s': %s",
error_set (e, "cannot create directory `%s': %s",
path, "file exists but is not a directory");
return false;
}
@ -1574,14 +1543,6 @@ xssl_get_error (SSL *ssl, int result, const char **error_info)
// --- 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 *
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;
free (re);
error_set (e, REGEX_ERROR, REGEX_ERROR_COMPILATION_FAILED,
"%s: %s", "failed to compile regular expression", desc.str);
error_set (e, "%s: %s", "failed to compile regular expression", desc.str);
str_free (&desc);
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.
static size_t config_error_domain_tag;
#define CONFIG_ERROR (error_resolve_domain (&config_error_domain_tag))
enum
{
CONFIG_ERROR_MALFORMED
};
struct config_item
{
const char *key;
@ -1828,8 +1780,8 @@ read_config_file (struct str_map *config, struct error **e)
FILE *fp = fopen (filename, "r");
if (!fp)
{
error_set (e, IO_ERROR, IO_ERROR_FAILED,
"could not open `%s' for reading: %s", filename, strerror (errno));
error_set (e, "could not open `%s' for reading: %s",
filename, strerror (errno));
return false;
}
@ -1851,8 +1803,8 @@ read_config_file (struct str_map *config, struct error **e)
{
if (*start)
{
error_set (e, CONFIG_ERROR, CONFIG_ERROR_MALFORMED,
"line %u in config: %s", line_no, "malformed input");
error_set (e, "line %u in config: %s",
line_no, "malformed input");
errors = true;
break;
}
@ -1907,8 +1859,8 @@ write_default_config (const char *filename, const char *prolog,
FILE *fp = fopen (path.str, "w");
if (!fp)
{
error_set (e, IO_ERROR, IO_ERROR_FAILED,
"could not open `%s' for writing: %s", path.str, strerror (errno));
error_set (e, "could not open `%s' for writing: %s",
path.str, strerror (errno));
goto error;
}
@ -1927,8 +1879,7 @@ write_default_config (const char *filename, const char *prolog,
fclose (fp);
if (errno)
{
error_set (e, IO_ERROR, IO_ERROR_FAILED,
"writing to `%s' failed: %s", path.str, strerror (errno));
error_set (e, "writing to `%s' failed: %s", path.str, strerror (errno));
goto error;
}

View File

@ -425,15 +425,6 @@ server_context_free (struct server_context *self)
// --- 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
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);
if (!path)
{
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s",
"cannot open file", catalog);
error_set (e, "%s: %s", "cannot open file", catalog);
return false;
}
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)
{
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s",
error_set (e, "%s: %s",
"failed reading the message catalog file", strerror (errno));
return false;
}
@ -1167,8 +1157,7 @@ irc_initialize_motd (struct server_context *ctx, struct error **e)
char *path = resolve_config_filename (motd);
if (!path)
{
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s",
"cannot open file", motd);
error_set (e, "%s: %s", "cannot open file", motd);
return false;
}
FILE *fp = fopen (path, "r");
@ -1176,7 +1165,7 @@ irc_initialize_motd (struct server_context *ctx, struct error **e)
if (!fp)
{
error_set (e, IO_ERROR, IO_ERROR_FAILED, "%s: %s",
error_set (e, "%s: %s",
"failed reading the MOTD file", strerror (errno));
return false;
}
@ -1201,9 +1190,8 @@ irc_initialize_server_name (struct server_context *ctx, struct error **e)
res = irc_validate_hostname (server_name);
if (res != VALIDATION_OK)
{
error_set (e, NETWORK_ERROR, NETWORK_ERROR_INVALID_CONFIGURATION,
"invalid configuration value for `%s': %s", "server_name",
irc_validate_to_str (res));
error_set (e, "invalid configuration value for `%s': %s",
"server_name", irc_validate_to_str (res));
return false;
}
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];
if (gethostname (hostname, sizeof hostname))
{
error_set (e, NETWORK_ERROR, NETWORK_ERROR_INVALID_CONFIGURATION,
"%s: %s", "getting the hostname failed", strerror (errno));
error_set (e, "%s: %s",
"getting the hostname failed", strerror (errno));
return false;
}
res = irc_validate_hostname (hostname);
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",
"server_name", hostname, irc_validate_to_str (res));
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);
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));
return false;
}
@ -1291,8 +1279,7 @@ irc_listen (struct server_context *ctx, struct error **e)
if (!gai_iter)
{
error_set (e, NETWORK_ERROR, NETWORK_ERROR_FAILED,
"network setup failed");
error_set (e, "network setup failed");
return false;
}

View File

@ -106,15 +106,6 @@ plugin_data_free (struct plugin_data *self)
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 str_map config; ///< User configuration
@ -306,8 +297,7 @@ error_ssl_2:
error_ssl_1:
// XXX: these error strings are really nasty; also there could be
// multiple errors on the OpenSSL stack.
error_set (e, CONNECT_ERROR, CONNECT_ERROR_FAILED,
"%s: %s", "could not initialize SSL",
error_set (e, "%s: %s", "could not initialize SSL",
ERR_error_string (ERR_get_error (), NULL));
return false;
}
@ -325,7 +315,7 @@ irc_establish_connection (struct bot_context *ctx,
int err = getaddrinfo (host, port, &gai_hints, &gai_result);
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));
return false;
}
@ -367,7 +357,7 @@ irc_establish_connection (struct bot_context *ctx,
if (!gai_iter)
{
error_set (e, CONNECT_ERROR, CONNECT_ERROR_FAILED, "connection failed");
error_set (e, "connection failed");
return false;
}
@ -633,16 +623,6 @@ setup_recovery_handler (struct bot_context *ctx)
/// The name of the special IRC command for interprocess communication
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 *
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");
if (!plugin_dir)
{
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_LOADING_FAILED,
"plugin directory not set");
error_set (e, "plugin directory not set");
return false;
}
if (!is_valid_plugin_name (name))
{
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_LOADING_FAILED,
"invalid plugin name");
error_set (e, "invalid plugin name");
return false;
}
if (str_map_find (&ctx->plugins_by_name, name))
{
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_ALREADY_LOADED,
"the plugin has already been loaded");
error_set (e, "the plugin has already been loaded");
return false;
}
int stdin_pipe[2];
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));
goto fail_1;
}
@ -953,7 +930,7 @@ plugin_load (struct bot_context *ctx, const char *name, struct error **e)
int stdout_pipe[2];
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));
goto fail_2;
}
@ -964,7 +941,7 @@ plugin_load (struct bot_context *ctx, const char *name, struct error **e)
pid_t pid = fork ();
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));
goto fail_3;
}
@ -1034,8 +1011,7 @@ plugin_unload (struct bot_context *ctx, const char *name, struct error **e)
if (!plugin)
{
error_set (e, PLUGIN_ERROR, PLUGIN_ERROR_NOT_LOADED,
"no such plugin is loaded");
error_set (e, "no such plugin is loaded");
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?
if (!irc_host)
{
error_set (e, CONNECT_ERROR, CONNECT_ERROR_INVALID_CONFIGURATION,
"no hostname specified in configuration");
error_set (e, "no hostname specified in configuration");
return false;
}
bool use_ssl;
if (!set_boolean_if_valid (&use_ssl, ssl_use_str))
{
error_set (e, CONNECT_ERROR, CONNECT_ERROR_INVALID_CONFIGURATION,
"invalid configuration value for `%s'", "use_ssl");
error_set (e, "invalid configuration value for `%s'", "use_ssl");
return false;
}