本文共 12639 字,大约阅读时间需要 42 分钟。
|
//sqlite 提供 error 的手段比较多 1. 直接返回错误原因 2. 返回错误码,有个函数可以根据错误码提取出错原因: 这个函数是 sqlite 里面比较亲切的函数: const char *sqlite_error_string (int rc); 多用这个函数,你会发现 sqlite 原来这么简单; sqlite 算是在嵌入式 Linux 产品中用的较广泛的数据库了,这个开源项目提供的 error code/error string 是继承自 Glib, 并发扬广大了; |
// 原型 gboolean gconf_init ( GError **error ) ; GError *error = NULL; if (!gconf_init (&error)) { fprintf (stderr, “Failed to initialize gconf, reason: %s/n”, error->message); g_error_free (error); error = NULL; } // 在 gconf 系统里面,主要复制了 GError 的一套内容,并且把出错信息填充到 GError 中, 这样调用者就可以很好的获取出错信息; gconf 也是嵌入式 Linux 产品中使用的较多的用于记录 setting 的开源项目,对于出错的处理,继承自 Glib ,并没有向 Sqlite 那样做了扩充,应该说是中规中矩吧,也可以了。 |
/* ** Return values for sqlite3_exec() and sqlite3_step() */ #define SQLITE_OK 0 /* Successful result */ /* beginning-of-error-codes */ #define SQLITE_ERROR 1 /* SQL error or missing database */ #define SQLITE_INTERNAL 2 /* NOT USED. Internal logic error in SQLite */ // … 参考 sqlite.h.in 文件,编译后放在 sqlite.h 中 #define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ /* end-of-error-codes */ |
const char *sqlite3ErrStr(int rc){ const char *z; switch( rc & 0xff ){ case SQLITE_ROW: case SQLITE_DONE: case SQLITE_OK: z = "not an error"; break; case SQLITE_ERROR: z = "SQL logic error or missing database"; break; // 参考 sqlite/src/main.c 中 default: z = "unknown error"; break; } return z; } |
const char *sqlite3_errmsg(sqlite3 *db) ; const void *sqlite3_errmsg16(sqlite3 *db) ; int sqlite3_errcode(sqlite3 *db) |
/* Sync with ConfigErrorType in GConf.idl, and some switch statements in the code */ typedef enum { /*< prefix=GCONF_ERROR >*/ GCONF_ERROR_SUCCESS = 0, GCONF_ERROR_FAILED = 1, /* Something didn't work, don't know why, probably unrecoverable // … 参考 gconf-error.h GCONF_ERROR_IN_SHUTDOWN = 16 /* server is shutting down */ } GConfError; |
static const gchar* err_msgs[] = { N_("Success"), N_("Failed"), // … 参考 gconf-error.c N_("No database available to save your configuration") }; |
#define GCONF_ERROR gconf_error_quark () GQuark gconf_error_quark (void) { static GQuark err_q = 0; if (err_q == 0) err_q = g_quark_from_static_string ("gconf-error-quark"); return err_q; } |
static GError* gconf_error_new_valist(GConfError en, const gchar* fmt, va_list args); GError* gconf_error_new(GConfError en, const gchar* fmt, ...); void gconf_set_error ( GError** err, GConfError en, const gchar* fmt, ...); // … 具体参考gconf-error.c |
typedef enum { GST_ CORE_ERROR_FAILED = 1, GST_ CORE_ERROR_TOO_LAZY, GST_ CORE_ERROR_NOT_IMPLEMENTED, GST_ CORE_ERROR_STATE_CHANGE, GST_ CORE_ERROR_PAD, GST_ CORE_ERROR_THREAD, GST_ CORE_ERROR_NEGOTIATION, GST_ CORE_ERROR_EVENT, GST_ CORE_ERROR_SEEK, GST_ CORE_ERROR_CAPS, GST_ CORE_ERROR_TAG, GST_ CORE_ERROR_MISSING_PLUGIN, GST_ CORE_ERROR_CLOCK, GST_CORE_ERROR_NUM_ERRORS } GstCoreError; |
typedef enum { GST_ LIBRARY_ERROR_FAILED = 1, GST_ LIBRARY_ERROR_TOO_LAZY, GST_ LIBRARY_ERROR_INIT, GST_ LIBRARY_ERROR_SHUTDOWN, GST_ LIBRARY_ERROR_SETTINGS, GST_ LIBRARY_ERROR_ENCODE, GST_LIBRARY_ERROR_NUM_ERRORS } GstLibraryError; |
typedef enum { GST_ RESOURCE_ERROR_FAILED = 1, GST_ RESOURCE_ERROR_TOO_LAZY, GST_ RESOURCE_ERROR_NOT_FOUND, GST_ RESOURCE_ERROR_BUSY, GST_ RESOURCE_ERROR_OPEN_READ, GST_ RESOURCE_ERROR_OPEN_WRITE, GST_ RESOURCE_ERROR_OPEN_READ_WRITE, GST_ RESOURCE_ERROR_CLOSE, GST_ RESOURCE_ERROR_READ, GST_ RESOURCE_ERROR_WRITE, GST_ RESOURCE_ERROR_SEEK, GST_ RESOURCE_ERROR_SYNC, GST_ RESOURCE_ERROR_SETTINGS, GST_ RESOURCE_ERROR_NO_SPACE_LEFT, GST_RESOURCE_ERROR_NUM_ERRORS } GstResourceError; |
typedef enum { GST_ STREAM_ERROR_FAILED = 1, GST_ STREAM_ERROR_TOO_LAZY, GST_ STREAM_ERROR_NOT_IMPLEMENTED, GST_ STREAM_ERROR_TYPE_NOT_FOUND, GST_ STREAM_ERROR_WRONG_TYPE, GST_ STREAM_ERROR_CODEC_NOT_FOUND, GST_ STREAM_ERROR_DECODE, GST_ STREAM_ERROR_ENCODE, GST_ STREAM_ERROR_DEMUX, GST_ STREAM_ERROR_MUX, GST_ STREAM_ERROR_FORMAT, GST_STREAM_ERROR_NUM_ERRORS } GstStreamError; |
#define QUARK_FUNC(string) / GQuark gst_ ## string ## _error_quark (void) { / static GQuark quark; / if (!quark) / quark = g_quark_from_static_string ("gst-" # string "-error-quark"); / return quark; } |
QUARK_FUNC ( core ); QUARK_FUNC ( library ); QUARK_FUNC ( resource ); QUARK_FUNC ( stream ); |
GQuark gst_core_error_quark (void){ //…} GQuark gst_library_error_quark (void) { //…} GQuark gst_ resource _error_quark (void) { //…} GQuark gst_stream_error_quark (void) { //…} // 为了方便起见,再定义 二代身份证 #define GST_LIBRARY_ERROR gst_library_error_quark () #define GST_RESOURCE_ERROR gst_resource_error_quark () #define GST_CORE_ERROR gst_core_error_quark () #define GST_STREAM_ERROR gst_stream_error_quark () |
#define TABLE(t, d, a, b) t[GST_ ## d ## _ERROR_ ## a] = g_strdup (b) |
static gchar ** _gst_core_errors_init (void) { gchar **t = NULL; t = g_new0 (gchar *, GST_CORE_ERROR_NUM_ERRORS); TABLE (t, CORE, FAILED, N_(" GStreamer encountered a general core library error.")); TABLE (t, CORE, TOO_LAZY, N_( "GStreamer developers were too lazy to assign an error code " "to this error." FILE_A_BUG)); TABLE (t, CORE, NOT_IMPLEMENTED, N_(" Internal GStreamer error: code not implemented." FILE_A_BUG)); TABLE (t, CORE, STATE_CHANGE, N_(" Internal GStreamer error: state change failed." FILE_A_BUG)); TABLE (t, CORE, PAD, N_(" Internal GStreamer error: pad problem." FILE_A_BUG)); TABLE (t, CORE, THREAD, N_(" Internal GStreamer error: thread problem." FILE_A_BUG)); TABLE (t, CORE, NEGOTIATION, N_(" Internal GStreamer error: negotiation problem." FILE_A_BUG)); TABLE (t, CORE, EVENT, N_(" Internal GStreamer error: event problem." FILE_A_BUG)); TABLE (t, CORE, SEEK, N_(" Internal GStreamer error: seek problem." FILE_A_BUG)); TABLE (t, CORE, CAPS, N_(" Internal GStreamer error: caps problem." FILE_A_BUG)); TABLE (t, CORE, TAG, N_(" Internal GStreamer error: tag problem." FILE_A_BUG)); TABLE (t, CORE, MISSING_PLUGIN, N_(" Your GStreamer installation is missing a plug-in.")); TABLE (t, CORE, CLOCK, N_(" Internal GStreamer error: clock problem." FILE_A_BUG)); return t; } //上面的函数的执行后的结果 gchar **gst_core_errors = _gst_core_errors_init (); gst_core_errors [GST_ CORE_ERROR_FAILED] = "GStreamer encountered a general core library error." gst_core_errors [GST_ CORE_ERROR_TOO_LAZY] = "GStreamer developers were too lazy to assign an error code to this error." //… 这样,用户就可以根据error code得出对应的error string了。 |
static gchar ** _gst_library_errors_init (void) { // …. 省略 return t; } |
/* initialize the dynamic table of translated resource errors */ static gchar ** _gst_resource_errors_init (void) { // …. 省略 } |
static gchar ** _gst_stream_errors_init (void) { // …. 省略 } |
gchar * gst_error_get_message (GQuark domain, gint code) { static gchar **gst_core_errors = NULL; static gchar **gst_library_errors = NULL; static gchar **gst_resource_errors = NULL; static gchar **gst_stream_errors = NULL; gchar *message = NULL; /* initialize error message tables if necessary */ if (gst_core_errors == NULL) gst_core_errors = _gst_core_errors_init (); if (gst_library_errors == NULL) gst_library_errors = _gst_library_errors_init (); if (gst_resource_errors == NULL) gst_resource_errors = _gst_resource_errors_init (); if (gst_stream_errors == NULL) gst_stream_errors = _gst_stream_errors_init (); // 根据 身份证 和 error code , 提取 error string. if (domain == GST_CORE_ERROR) message = gst_core_errors[code]; else if (domain == GST_LIBRARY_ERROR) message = gst_library_errors[code]; else if (domain == GST_RESOURCE_ERROR) message = gst_resource_errors[code]; else if (domain == GST_STREAM_ERROR) message = gst_stream_errors[code]; else { g_warning ("No error messages for domain %s", g_quark_to_string (domain)); return g_strdup_printf (_("No error message for domain %s."), g_quark_to_string (domain)); } if (message) return g_strdup (_(message)); else return g_strdup_printf (_ ("No standard error message for domain %s and code %d."), g_quark_to_string (domain), code); } |
typedef struct DBusError DBusError; /** * Object representing an exception. */ struct DBusError { const char *name; /**< error name */ // 主要的 const char *message; /**< error message */ // 主要的 unsigned int dummy1 : 1; /**< placeholder */ unsigned int dummy2 : 1; /**< placeholder */ unsigned int dummy3 : 1; /**< placeholder */ unsigned int dummy4 : 1; /**< placeholder */ unsigned int dummy5 : 1; /**< placeholder */ void *padding1; /**< placeholder */ }; |
// 分配内存 void dbus_error_init (DBusError *error); // 释放 void dbus_error_free (DBusError *error); // 这是 dbus 的特色菜肴,能灵活的对 DBusError 填充想填充的内容,不必事先定死 void dbus_set_error (DBusError *error, const char *name, const char *message, ...); // 这个是上面那个函数的简化版本 void dbus_set_error_const (DBusError *error, const char *name, const char *message); void dbus_move_error (DBusError *src, DBusError *dest); // 查询之用 dbus_bool_t dbus_error_has_name (const DBusError *error, const char *name); dbus_bool_t dbus_error_is_set (const DBusError *error); |
#define DBUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed" #define DBUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" //……., 参考 dbus-protocol.h #define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown" |
DBusError error; dbus_error_init (&error); 比如说 dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); 或者: // 这个就是往 DBusError 的 message 字段填充可变参数,这样信息可以灵活点 dbus_set_error (error, DBUS_ERROR_SPAWN_CHILD_SIGNALED, "Process %s received signal %d", sitter->executable, WTERMSIG (sitter->status)); |
//同样也是初始化一个error DBusError error; dbus_error_init (&error); // 然后调用 dbus API If (!dbus_message_get_args (msg, &error, …) { printf (“Can’t get arguments: %s”, error.message); dbus_error_free (&error); // 别忘记释放 } |
转载地址:http://oitgb.baihongyu.com/