Skip to content
Snippets Groups Projects
Commit 607f1775 authored by Colin Walters's avatar Colin Walters
Browse files

errors: Add GLNX_AUTO_PREFIX_ERROR

In a lot of places in ostree, we end up prefixing errors in the *caller*.
Often we only have 1-2 callers, and doing the error prefixing isn't
too duplicative.  But there are definitely cases where it's cleaner
to do the prefixing in the callee.  We have functions that aren't
ported to new style for this reason (they still do the prefixing
in `out:`).

Introduce a cleanup-oriented version of error prefixing so we can port those
functions too.
parent 61ef326a
No related branches found
No related tags found
No related merge requests found
...@@ -84,6 +84,36 @@ glnx_prefix_error (GError **error, const char *fmt, ...) ...@@ -84,6 +84,36 @@ glnx_prefix_error (GError **error, const char *fmt, ...)
#define glnx_prefix_error_null(error, args...) \ #define glnx_prefix_error_null(error, args...) \
({glnx_prefix_error (error, args); NULL;}) ({glnx_prefix_error (error, args); NULL;})
/**
* GLNX_AUTO_PREFIX_ERROR:
*
* An autocleanup-based macro to automatically call `g_prefix_error()` (also with a colon+space `: `)
* when it goes out of scope. This is useful when one wants error strings built up by the callee
* function, not all callers.
*
* ```
* gboolean start_http_request (..., GError **error)
* {
* GLNX_AUTO_PREFIX_ERROR("HTTP request", error)
*
* if (!libhttp_request_start (..., error))
* return FALSE;
* ...
* return TRUE;
* ```
*/
typedef struct {
const char *prefix;
GError **error;
} GLnxAutoErrorPrefix;
static inline void
glnx_cleanup_auto_prefix_error (GLnxAutoErrorPrefix *prefix)
{
g_prefix_error (prefix->error, "%s: ", prefix->prefix);
}
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(GLnxAutoErrorPrefix, glnx_cleanup_auto_prefix_error)
#define GLNX_AUTO_PREFIX_ERROR(text, error) g_auto(GLnxAutoErrorPrefix) _GLNX_MAKE_ANONYMOUS(_glnxautoprefixerror_) = { text, error }
/* Set @error using the value of `g_strerror (errno)`. /* Set @error using the value of `g_strerror (errno)`.
* *
* This function returns %FALSE so it can be used conveniently in a single * This function returns %FALSE so it can be used conveniently in a single
......
...@@ -125,6 +125,48 @@ test_error_errno (void) ...@@ -125,6 +125,48 @@ test_error_errno (void)
g_assert_cmpint (fd, ==, -1); g_assert_cmpint (fd, ==, -1);
} }
static void
test_error_auto_nothrow (GError **error)
{
GLNX_AUTO_PREFIX_ERROR("foo", error);
/* Side effect to avoid otherwise empty function */
g_assert_no_error (*error);
}
static void
test_error_auto_throw (GError **error)
{
GLNX_AUTO_PREFIX_ERROR("foo", error);
(void) glnx_throw (error, "oops");
}
static void
test_error_auto_throw_recurse (GError **error)
{
GLNX_AUTO_PREFIX_ERROR("foo", error);
if (TRUE)
{
GLNX_AUTO_PREFIX_ERROR("bar", error);
(void) glnx_throw (error, "oops");
}
}
static void
test_error_auto (void)
{
g_autoptr(GError) error = NULL;
test_error_auto_nothrow (&error);
g_assert_no_error (error);
test_error_auto_throw (&error);
g_assert_nonnull (error);
g_assert_cmpstr (error->message, ==, "foo: oops");
g_clear_error (&error);
test_error_auto_throw_recurse (&error);
g_assert_nonnull (error);
g_assert_cmpstr (error->message, ==, "foo: bar: oops");
}
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
int ret; int ret;
...@@ -133,6 +175,7 @@ int main (int argc, char **argv) ...@@ -133,6 +175,7 @@ int main (int argc, char **argv)
g_test_add_func ("/error-throw", test_error_throw); g_test_add_func ("/error-throw", test_error_throw);
g_test_add_func ("/error-errno", test_error_errno); g_test_add_func ("/error-errno", test_error_errno);
g_test_add_func ("/error-auto", test_error_auto);
ret = g_test_run(); ret = g_test_run();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment