D-Bus 错误处理

D-Bus 错误处理

所有从远程方法返回错误(如 g_dbus_connection_call_sync())的设施都使用 GError 来表示 D-Bus 错误(例如来自另一对等的错误)和本地进程中生成的错误。

要检查返回的 GError 是否来自远程对等,请使用 g_dbus_error_is_remote_error()。要获取实际的 D-Bus 错误名称,请使用 g_dbus_error_get_remote_error()。在展示错误之前,始终使用 g_dbus_error_strip_remote_error()

此外,用于将错误返回给远程对等的设施也使用 GError。有关 D-Bus 错误名称设置的讨论,请参阅 g_dbus_method_invocation_return_error()

应用程序可以将 GError 错误域与一组 D-Bus 错误相关联,以便将 D-Bus 错误自动映射到 GError 并回过来。这通常是在返回错误域 GQuark 的函数中完成的

// 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;
}

有了这个配置,D-Bus 对等实体可以透明地传递例如 FOO_BAR_ERROR_ANOTHER_ERROR,其他对等实体将看到 D-Bus 错误名称 org.project.Foo.Bar.Error.AnotherError

如果其他对等实体使用 GDBus,并且提前通过 g_dbus_error_register_error_domain() 注册了关联(例如,在先前的示例中通过调用 FOO_BAR_ERROR 标量生成本身),则对等实体还将看到 FOO_BAR_ERROR_ANOTHER_ERROR 而不是 G_IO_ERROR_DBUS_ERROR。请注意,GDBus 客户端仍然可以使用 g_dbus_error_get_remote_error() 恢复 org.project.Foo.Bar.Error.AnotherError

请注意,G_DBUS_ERROR 错误域仅用于从远程消息总线进程返回错误。例如由 GDBusConnection 在进程内本地生成的错误应使用 G_IO_ERROR 域。