From 461ef02b7cbb9326212d4dcba903c8cd840d46b9 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Wed, 28 Sep 2011 17:23:18 +0100 Subject: [PATCH 06/10] MyObject: make ThrowError, AsyncThrowError throw a caller-specified error This can be used to test arbitrary errors, but only in-process; in tests with the service out-of-process, like test-dbus-glib, the initial error (matching the error they previously threw) will always be used. This obsoletes ThrowErrorUnderscore, ThrowErrorMultiWord and ThrowNotSupported, but not ThrowUnregisteredError due to some strange assumptions about the validity of GError domains in that method (see GNOME#660731). Signed-off-by: Simon McVittie Bug: https://bugs.freedesktop.org/show_bug.cgi?id=40151 --- test/core/my-object.c | 49 +++++++++++++++++++++++++++++++++++-------------- test/core/my-object.h | 5 +++++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/test/core/my-object.c b/test/core/my-object.c index 426f056..e3636b5 100644 --- a/test/core/my-object.c +++ b/test/core/my-object.c @@ -50,6 +50,7 @@ my_object_finalize (GObject *object) MyObject *mobject = MY_OBJECT (object); g_free (mobject->this_is_a_string); + g_clear_error (&mobject->saved_error); (G_OBJECT_CLASS (my_object_parent_class)->finalize) (object); } @@ -128,6 +129,8 @@ my_object_init (MyObject *obj) { obj->val = 0; obj->notouching = 42; + obj->saved_error = g_error_new_literal (MY_OBJECT_ERROR, + MY_OBJECT_ERROR_FOO, "this method always loses"); } static void @@ -291,14 +294,21 @@ my_object_increment_retval_error (MyObject *obj, gint32 x, GError **error) return x + 1; } +void +my_object_save_error (MyObject *obj, + GQuark domain, + gint code, + const gchar *message) +{ + g_clear_error (&obj->saved_error); + g_set_error_literal (&obj->saved_error, domain, code, message); +} + gboolean my_object_throw_error (MyObject *obj, GError **error) { - g_set_error (error, - MY_OBJECT_ERROR, - MY_OBJECT_ERROR_FOO, - "%s", - "this method always loses"); + g_set_error_literal (error, obj->saved_error->domain, + obj->saved_error->code, obj->saved_error->message); return FALSE; } @@ -340,6 +350,14 @@ my_object_throw_unregistered_error (MyObject *obj, GError **error) { /* Unregistered errors shouldn't cause a dbus abort. See * https://bugzilla.redhat.com/show_bug.cgi?id=581794 + * + * This is arguably invalid usage - a domain of 0 (which stringifies + * to NULL) is meaningless. (See GNOME#660731.) + * + * We can't just use my_object_save_error() and ThrowError() for + * this, because g_error_new() is stricter about the domain than + * g_error_new_valist(). Perhaps this method should be removed entirely, + * though. */ g_set_error (error, 0, 0, "%s", @@ -853,15 +871,16 @@ my_object_async_increment (MyObject *obj, gint32 x, DBusGMethodInvocation *conte g_idle_add ((GSourceFunc)do_async_increment, data); } +typedef struct { + GError *error; + DBusGMethodInvocation *context; +} ErrorData; + static gboolean -do_async_error (IncrementData *data) +do_async_error (ErrorData *data) { - GError *error; - error = g_error_new (MY_OBJECT_ERROR, - MY_OBJECT_ERROR_FOO, - "%s", - "this method always loses"); - dbus_g_method_return_error (data->context, error); + dbus_g_method_return_error (data->context, data->error); + g_error_free (data->error); g_free (data); return FALSE; } @@ -869,9 +888,11 @@ do_async_error (IncrementData *data) void my_object_async_throw_error (MyObject *obj, DBusGMethodInvocation *context) { - IncrementData *data = g_new0(IncrementData, 1); + ErrorData *data = g_new0 (ErrorData, 1); + + data->error = g_error_copy (obj->saved_error); data->context = context; - g_idle_add ((GSourceFunc)do_async_error, data); + g_idle_add ((GSourceFunc) do_async_error, data); } void diff --git a/test/core/my-object.h b/test/core/my-object.h index 0fcfee2..d50d0b4 100644 --- a/test/core/my-object.h +++ b/test/core/my-object.h @@ -13,6 +13,7 @@ GType my_object_get_type (void); struct MyObject { GObject parent; + GError *saved_error; char *this_is_a_string; guint notouching; guint val; @@ -119,4 +120,8 @@ void my_object_unsafe_disable_legacy_property_access (MyObject *obj); void my_object_emit_objectified (MyObject *obj, GObject *other); +/* Not a D-Bus method. */ +void my_object_save_error (MyObject *obj, GQuark domain, gint code, + const gchar *message); + #endif -- 1.7.6.3