D-Bus Error Handling
D-Bus Error Handling
All facilities that return errors from remote methods (such as
g_dbus_connection_call_sync()
) use GError
to represent both
D-Bus errors (e.g. errors returned from the other peer) and locally in-process
generated errors.
To check if a returned GError
is an error from a remote peer, use
g_dbus_error_is_remote_error()
. To get the actual D-Bus error name,
use g_dbus_error_get_remote_error()
. Before presenting an error, always
use g_dbus_error_strip_remote_error()
.
In addition, facilities used to return errors to a remote peer also use
GError
. See g_dbus_method_invocation_return_error()
for
discussion about how the D-Bus error name is set.
Applications can associate a GError
error domain with a set of D-Bus
errors in order to automatically map from D-Bus errors to GError
and
back. This is typically done in the function returning the GQuark
for
the error domain:
// foo-bar-error.h:
#define FOO_BAR_ERROR (foo_bar_error_quark ())
GQuark foo_bar_error_quark (void);
typedef enum
{
FOO_BAR_ERROR_FAILED,
FOO_BAR_ERROR_ANOTHER_ERROR,
FOO_BAR_ERROR_SOME_THIRD_ERROR,
FOO_BAR_N_ERRORS / *< skip >* /
} FooBarError;
// foo-bar-error.c:
static const GDBusErrorEntry foo_bar_error_entries[] =
{
{FOO_BAR_ERROR_FAILED, "org.project.Foo.Bar.Error.Failed"},
{FOO_BAR_ERROR_ANOTHER_ERROR, "org.project.Foo.Bar.Error.AnotherError"},
{FOO_BAR_ERROR_SOME_THIRD_ERROR, "org.project.Foo.Bar.Error.SomeThirdError"},
};
// Ensure that every error code has an associated D-Bus error name
G_STATIC_ASSERT (G_N_ELEMENTS (foo_bar_error_entries) == FOO_BAR_N_ERRORS);
GQuark
foo_bar_error_quark (void)
{
static gsize quark = 0;
g_dbus_error_register_error_domain ("foo-bar-error-quark",
&quark,
foo_bar_error_entries,
G_N_ELEMENTS (foo_bar_error_entries));
return (GQuark) quark;
}
With this setup, a D-Bus peer can transparently pass e.g.
FOO_BAR_ERROR_ANOTHER_ERROR
and other peers will see the D-Bus error name
org.project.Foo.Bar.Error.AnotherError
.
If the other peer is using GDBus, and has registered the association with
g_dbus_error_register_error_domain()
in advance (e.g. by invoking the
FOO_BAR_ERROR
quark generation itself in the previous example) the peer will
see also FOO_BAR_ERROR_ANOTHER_ERROR
instead of G_IO_ERROR_DBUS_ERROR
. Note
that GDBus clients can still recover org.project.Foo.Bar.Error.AnotherError
using g_dbus_error_get_remote_error()
.
Note that the G_DBUS_ERROR
error domain is intended only for returning errors
from a remote message bus process. Errors generated locally in-process by e.g.
GDBusConnection
should use the G_IO_ERROR
domain.