diff --git a/docs/reference/gio/dbus-error.md b/docs/reference/gio/dbus-error.md new file mode 100644 index 000000000..fc1a1a641 --- /dev/null +++ b/docs/reference/gio/dbus-error.md @@ -0,0 +1,79 @@ +Title: D-Bus Error Handling +SPDX-License-Identifier: LGPL-2.1-or-later +SPDX-FileCopyrightText: 2010 David Zeuthen +SPDX-FileCopyrightText: 2012 Aleksander Morgado + +# D-Bus Error Handling + +All facilities that return errors from remote methods (such as +[method@Gio.DBusConnection.call_sync]) use [type@GLib.Error] 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 [type@GLib.Error] is an error from a remote peer, use +[func@Gio.DBusError.is_remote_error]. To get the actual D-Bus error name, +use [func@Gio.DBusError.get_remote_error]. Before presenting an error, always +use [func@Gio.DBusError.strip_remote_error]. + +In addition, facilities used to return errors to a remote peer also use +[type@GLib.Error]. See [method@Gio.DBusMethodInvocation.return_error] for +discussion about how the D-Bus error name is set. + +Applications can associate a [type@GLib.Error] error domain with a set of D-Bus +errors in order to automatically map from D-Bus errors to [type@GLib.Error] and +back. This is typically done in the function returning the [type@GLib.Quark] for +the error domain: + +```c +// 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 +[func@Gio.DBusError.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 [func@Gio.DBusError.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. +[class@Gio.DBusConnection] should use the `G_IO_ERROR` domain. + diff --git a/docs/reference/gio/gio.toml.in b/docs/reference/gio/gio.toml.in index 5e6386055..e72ed32bb 100644 --- a/docs/reference/gio/gio.toml.in +++ b/docs/reference/gio/gio.toml.in @@ -43,6 +43,7 @@ content_files = [ "overview.md", "file-attributes.md", "tls-overview.md", + "dbus-error.md", "migrating-gdbus.md", "migrating-gconf.md", diff --git a/docs/reference/gio/meson.build b/docs/reference/gio/meson.build index f3164fae5..ad22dd6eb 100644 --- a/docs/reference/gio/meson.build +++ b/docs/reference/gio/meson.build @@ -225,6 +225,7 @@ endif # gi-docgen version expand_content_files = [ + 'dbus-error.md', 'file-attributes.md', 'migrating-gconf.md', 'migrating-gdbus.md', diff --git a/gio/gdbuserror.c b/gio/gdbuserror.c index 1cee9e58b..432b24c12 100644 --- a/gio/gdbuserror.c +++ b/gio/gdbuserror.c @@ -33,82 +33,6 @@ #include "glibintl.h" -/** - * SECTION:gdbuserror - * @title: GDBusError - * @short_description: Mapping D-Bus errors to and from GError - * @include: gio/gio.h - * - * 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. - */ - static const GDBusErrorEntry g_dbus_error_entries[] = { {G_DBUS_ERROR_FAILED, "org.freedesktop.DBus.Error.Failed"},