diff options
-rw-r--r-- | docs/reference/gdbus/gdbus-standalone-sections.txt | 5 | ||||
-rw-r--r-- | gdbus/gdbusconnection.c | 17 | ||||
-rw-r--r-- | gdbus/gdbuserror.c | 56 | ||||
-rw-r--r-- | gdbus/gdbuserror.h | 19 | ||||
-rw-r--r-- | gdbus/tests/connection.c | 4 | ||||
-rw-r--r-- | gdbus/tests/error.c | 18 | ||||
-rw-r--r-- | gdbus/tests/export.c | 2 | ||||
-rw-r--r-- | gdbus/tests/proxy.c | 7 | ||||
-rw-r--r-- | gdbus/tests/threading.c | 1 |
9 files changed, 87 insertions, 42 deletions
diff --git a/docs/reference/gdbus/gdbus-standalone-sections.txt b/docs/reference/gdbus/gdbus-standalone-sections.txt index c563595..c572812 100644 --- a/docs/reference/gdbus/gdbus-standalone-sections.txt +++ b/docs/reference/gdbus/gdbus-standalone-sections.txt @@ -94,8 +94,9 @@ g_bus_unwatch_proxy <FILE>gdbuserror</FILE> GDBusError G_DBUS_ERROR -g_dbus_error_get_dbus_error_name -g_dbus_error_strip +g_dbus_error_is_remote_error +g_dbus_error_get_remote_error +g_dbus_error_strip_remote_error g_dbus_error_register_error g_dbus_error_unregister_error g_dbus_error_new_for_dbus_error diff --git a/gdbus/gdbusconnection.c b/gdbus/gdbusconnection.c index 088bcb1..071ba6c 100644 --- a/gdbus/gdbusconnection.c +++ b/gdbus/gdbusconnection.c @@ -737,6 +737,8 @@ initable_init (GInitable *initable, dbus_error.name, dbus_error.message, NULL); + /* this is a locally generated error so strip the remote part */ + g_dbus_error_strip_remote_error (connection->priv->initialization_error); dbus_error_free (&dbus_error); g_propagate_error (error, g_error_copy (connection->priv->initialization_error)); } @@ -2647,14 +2649,11 @@ dbus_1_obj_vtable_message_func (DBusConnection *connection, if (ei->vtable == NULL || ei->vtable->handle_method_call == NULL) goto out; - /* Check that the incoming args are of the right type - if they are not, then fail - * with %G_DBUS_ERROR_INVALID_ARGS - */ - method_info = NULL; - /* TODO: the cost of this is O(n) - it might be worth caching the result */ method_info = g_dbus_interface_info_lookup_method (ei->introspection_data, dbus_message_get_member (message)); + /* if the method doesn't exist, return the org.freedesktop.DBus.Error.UnknownMethod + * error to the caller */ if (method_info == NULL) { reply = dbus_message_new_error (message, @@ -2666,6 +2665,9 @@ dbus_1_obj_vtable_message_func (DBusConnection *connection, goto out; } + /* Check that the incoming args are of the right type - if they are not, return + * the org.freedesktop.DBus.Error.InvalidArgs error to the caller + */ if (!dbus_message_has_signature (message, method_info->in_signature)) { reply = dbus_message_new_error (message, @@ -2848,6 +2850,11 @@ g_dbus_connection_register_object (GDBusConnection *connection, dbus_error.message, _("Another D-Bus binding is already exporting an object at %s"), object_path); + if (error != NULL) + { + /* this is a locally generated error so strip the remote part */ + g_dbus_error_strip_remote_error (*error); + } dbus_error_free (&dbus_error); goto out; } diff --git a/gdbus/gdbuserror.c b/gdbus/gdbuserror.c index 77ce26c..f211cd5 100644 --- a/gdbus/gdbuserror.c +++ b/gdbus/gdbuserror.c @@ -40,8 +40,10 @@ * Error helper functions for GDBus. * * All facilities in GDBus (such as g_dbus_connection_invoke_method_sync()) - * that return errors as a result of remote method invocations use #GError. To get - * the actual D-Bus error name, use g_dbus_error_get_dbus_error_name(). + * that return errors as a result of remote method invocations returning + * errors use #GError. To check if a returned #GError is the result of + * a remote error, use g_dbus_error_is_remote_error(). To get + * the actual D-Bus error name, use g_dbus_error_get_remote_error(). * * In addition, facilities that are used to return errors to a remote * caller also use #GError. See g_dbus_method_invocation_return_error() @@ -105,9 +107,9 @@ * </programlisting> * With this setup, a server can transparently pass e.g. %FOO_BAR_ERROR_ANOTHER_ERROR and * clients will see the D-Bus error name <literal>org.project.Foo.Bar.Error.AnotherError</literal>. - * If the client is using GDBus, the client will see also %FOO_BAR_ERROR_ANOTHER_ERROR instead + * If the client is using GDBus, the client will see also %FOO_BAR_ERROR_ANOTHER_ERROR instead * of %G_DBUS_ERROR_REMOTE_ERROR. Note that GDBus clients can still recover - * <literal>org.project.Foo.Bar.Error.AnotherError</literal> using g_dbus_error_get_dbus_error_name(). + * <literal>org.project.Foo.Bar.Error.AnotherError</literal> using g_dbus_error_get_remote_error(). */ /** @@ -436,19 +438,37 @@ g_dbus_error_unregister_error (GQuark error_domain, /* ---------------------------------------------------------------------------------------------------- */ /** - * g_dbus_error_get_dbus_error_name: + * g_dbus_error_is_remote_error: + * @error: A #GError. + * + * Checks if @error represents an error from a remote process. If so, + * use g_dbus_error_get_remote_error() to get the name of the error. + * + * Returns: %TRUE if @error represents an error from a remote process, + * %FALSE otherwise. + */ +gboolean +g_dbus_error_is_remote_error (const GError *error) +{ + g_return_val_if_fail (error != NULL, FALSE); + return g_str_has_prefix (error->message, "GDBus.Error:"); +} + + +/** + * g_dbus_error_get_remote_error: * @error: A #GError. * * Gets the D-Bus error name used for @error, if any. * * This function is guaranteed to return a D-Bus error name for all #GError<!-- -->s returned from * functions handling remote method calls (e.g. g_dbus_connection_invoke_method_finish()) - * unless g_dbus_error_strip() has been used on @error. + * unless g_dbus_error_strip_remote_error() has been used on @error. * * Returns: An allocated string or %NULL if the D-Bus error name could not be found. Free with g_free(). */ gchar * -g_dbus_error_get_dbus_error_name (const GError *error) +g_dbus_error_get_remote_error (const GError *error) { RegisteredError *re; gchar *ret; @@ -509,23 +529,23 @@ g_dbus_error_get_dbus_error_name (const GError *error) * * Errors registered with g_dbus_error_register_error() will be looked * up using @dbus_error_name and if a match is found, the error domain - * and code is used. Applications can use g_dbus_error_get_dbus_error_name() + * and code is used. Applications can use g_dbus_error_get_remote_error() * to recover @dbus_error_name. * * If a match against a registered error is not found and the D-Bus * error name is in a form as returned by g_dbus_error_encode_gerror() * the error domain and code encoded in the name is used to * create the #GError. Also, @dbus_error_name is added to the error message - * such that it can be recovered with g_dbus_error_get_dbus_error_name(). + * such that it can be recovered with g_dbus_error_get_remote_error(). * * Otherwise, a #GError with the error code %G_DBUS_ERROR_REMOTE_ERROR * in the #G_DBUS_ERROR error domain is returned. Also, @dbus_error_name is * added to the error message such that it can be recovered with - * g_dbus_error_get_dbus_error_name(). + * g_dbus_error_get_remote_error(). * * In all three cases, @dbus_error_name can always be recovered from the - * returned #GError using the g_dbus_error_get_dbus_error_name() function - * (unless g_dbus_error_strip() hasn't been used on the returned error). + * returned #GError using the g_dbus_error_get_remote_error() function + * (unless g_dbus_error_strip_remote_error() hasn't been used on the returned error). * * This function is typically only used in object mappings to prepare * #GError instances for applications. Regular applications should not use @@ -558,9 +578,11 @@ g_dbus_error_new_for_dbus_error (const gchar *dbus_error_name, if (re != NULL) { - error = g_error_new_literal (re->pair.error_domain, - re->pair.error_code, - dbus_error_message); + error = g_error_new (re->pair.error_domain, + re->pair.error_code, + "GDBus.Error:%s: %s", + dbus_error_name, + dbus_error_message); } else { @@ -673,7 +695,7 @@ g_dbus_error_set_dbus_error_valist (GError **error, } /** - * g_dbus_error_strip: + * g_dbus_error_strip_remote_error: * @error: A #GError. * * Looks for extra information in the error message used to recover @@ -686,7 +708,7 @@ g_dbus_error_set_dbus_error_valist (GError **error, * Returns: %TRUE if information was stripped, %FALSE otherwise. */ gboolean -g_dbus_error_strip (GError *error) +g_dbus_error_strip_remote_error (GError *error) { gboolean ret; diff --git a/gdbus/gdbuserror.h b/gdbus/gdbuserror.h index e5c80b6..3c426f0 100644 --- a/gdbus/gdbuserror.h +++ b/gdbus/gdbuserror.h @@ -41,17 +41,18 @@ G_BEGIN_DECLS GQuark g_dbus_error_quark (void); -/* Used by applications to get and strip the D-Bus error name */ -gchar *g_dbus_error_get_dbus_error_name (const GError *error); -gboolean g_dbus_error_strip (GError *error); +/* Used by applications to check, get and strip the D-Bus error name */ +gboolean g_dbus_error_is_remote_error (const GError *error); +gchar *g_dbus_error_get_remote_error (const GError *error); +gboolean g_dbus_error_strip_remote_error (GError *error); /* Used by applications to associate GError domains with D-Bus error names */ -gboolean g_dbus_error_register_error (GQuark error_domain, - gint error_code, - const gchar *dbus_error_name); -gboolean g_dbus_error_unregister_error (GQuark error_domain, - gint error_code, - const gchar *dbus_error_name); +gboolean g_dbus_error_register_error (GQuark error_domain, + gint error_code, + const gchar *dbus_error_name); +gboolean g_dbus_error_unregister_error (GQuark error_domain, + gint error_code, + const gchar *dbus_error_name); /* Only used by object mappings to map back and forth to GError */ GError *g_dbus_error_new_for_dbus_error (const gchar *dbus_error_name, diff --git a/gdbus/tests/connection.c b/gdbus/tests/connection.c index b74d679..43d9c37 100644 --- a/gdbus/tests/connection.c +++ b/gdbus/tests/connection.c @@ -47,6 +47,7 @@ test_connection_life_cycle (void) */ c = g_dbus_connection_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_FILE_NOT_FOUND); + g_assert (!g_dbus_error_is_remote_error (error)); g_assert (c == NULL); g_error_free (error); error = NULL; @@ -107,6 +108,7 @@ msg_cb_expect_error_disconnected (GDBusConnection *connection, res, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_DISCONNECTED); + g_assert (!g_dbus_error_is_remote_error (error)); g_error_free (error); g_assert (result == NULL); @@ -126,6 +128,7 @@ msg_cb_expect_error_unknown_method (GDBusConnection *connection, res, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD); + g_assert (g_dbus_error_is_remote_error (error)); g_assert (result == NULL); g_main_loop_quit (loop); @@ -163,6 +166,7 @@ msg_cb_expect_error_cancelled (GDBusConnection *connection, res, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_CANCELLED); + g_assert (!g_dbus_error_is_remote_error (error)); g_error_free (error); g_assert (result == NULL); diff --git a/gdbus/tests/error.c b/gdbus/tests/error.c index e8749d7..2c647da 100644 --- a/gdbus/tests/error.c +++ b/gdbus/tests/error.c @@ -38,8 +38,10 @@ check_registered_error (const gchar *given_dbus_error_name, error = g_dbus_error_new_for_dbus_error (given_dbus_error_name, "test message"); g_assert_error (error, error_domain, error_code); + g_assert (g_dbus_error_is_remote_error (error)); + g_assert (g_dbus_error_strip_remote_error (error)); g_assert_cmpstr (error->message, ==, "test message"); - dbus_error_name = g_dbus_error_get_dbus_error_name (error); + dbus_error_name = g_dbus_error_get_remote_error (error); g_assert_cmpstr (dbus_error_name, ==, given_dbus_error_name); g_free (dbus_error_name); g_error_free (error); @@ -85,16 +87,17 @@ check_unregistered_error (const gchar *given_dbus_error_name) error = g_dbus_error_new_for_dbus_error (given_dbus_error_name, "test message"); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_REMOTE_ERROR); - dbus_error_name = g_dbus_error_get_dbus_error_name (error); + g_assert (g_dbus_error_is_remote_error (error)); + dbus_error_name = g_dbus_error_get_remote_error (error); g_assert_cmpstr (dbus_error_name, ==, given_dbus_error_name); g_free (dbus_error_name); /* strip the message */ - g_assert (g_dbus_error_strip (error)); + g_assert (g_dbus_error_strip_remote_error (error)); g_assert_cmpstr (error->message, ==, "test message"); /* check that we can no longer recover the D-Bus error name */ - g_assert (g_dbus_error_get_dbus_error_name (error) == NULL); + g_assert (g_dbus_error_get_remote_error (error) == NULL); g_error_free (error); @@ -138,17 +141,18 @@ check_transparent_gerror (GQuark error_domain, error = g_dbus_error_new_for_dbus_error (given_dbus_error_name, "test message"); g_assert_error (error, error_domain, error_code); - dbus_error_name = g_dbus_error_get_dbus_error_name (error); + g_assert (g_dbus_error_is_remote_error (error)); + dbus_error_name = g_dbus_error_get_remote_error (error); g_assert_cmpstr (dbus_error_name, ==, given_dbus_error_name); g_free (dbus_error_name); g_free (given_dbus_error_name); /* strip the message */ - g_assert (g_dbus_error_strip (error)); + g_assert (g_dbus_error_strip_remote_error (error)); g_assert_cmpstr (error->message, ==, "test message"); /* check that we can no longer recover the D-Bus error name */ - g_assert (g_dbus_error_get_dbus_error_name (error) == NULL); + g_assert (g_dbus_error_get_remote_error (error) == NULL); g_error_free (error); } diff --git a/gdbus/tests/export.c b/gdbus/tests/export.c index 086103a..d15246c 100644 --- a/gdbus/tests/export.c +++ b/gdbus/tests/export.c @@ -380,6 +380,7 @@ test_object_registration (void) &data, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_OBJECT_PATH_IN_USE); + g_assert (!g_dbus_error_is_remote_error (error)); g_error_free (error); error = NULL; g_assert (registration_id == 0); @@ -409,6 +410,7 @@ test_object_registration (void) &data, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_OBJECT_PATH_IN_USE); + g_assert (!g_dbus_error_is_remote_error (error)); g_error_free (error); error = NULL; g_assert (registration_id == 0); diff --git a/gdbus/tests/proxy.c b/gdbus/tests/proxy.c index 193ab71..42bd1e6 100644 --- a/gdbus/tests/proxy.c +++ b/gdbus/tests/proxy.c @@ -67,11 +67,13 @@ test_methods (GDBusConnection *connection, NULL, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_REMOTE_ERROR); + g_assert (g_dbus_error_is_remote_error (error)); + g_assert (g_dbus_error_is_remote_error (error)); g_assert (result == NULL); - dbus_error_name = g_dbus_error_get_dbus_error_name (error); + dbus_error_name = g_dbus_error_get_remote_error (error); g_assert_cmpstr (dbus_error_name, ==, "com.example.TestException"); g_free (dbus_error_name); - g_assert (g_dbus_error_strip (error)); + g_assert (g_dbus_error_strip_remote_error (error)); g_assert_cmpstr (error->message, ==, "Yo is not a proper greeting"); g_clear_error (&error); @@ -84,6 +86,7 @@ test_methods (GDBusConnection *connection, NULL, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_NO_REPLY); + g_assert (g_dbus_error_is_remote_error (error)); g_assert (result == NULL); g_clear_error (&error); } diff --git a/gdbus/tests/threading.c b/gdbus/tests/threading.c index 88e206d..7b100a3 100644 --- a/gdbus/tests/threading.c +++ b/gdbus/tests/threading.c @@ -78,6 +78,7 @@ msg_cb_expect_error_cancelled (GDBusConnection *connection, res, &error); g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_CANCELLED); + g_assert (!g_dbus_error_is_remote_error (error)); g_error_free (error); g_assert (result == NULL); |