On Thu, Aug 21, 2014 at 10:59 AM, Gaute Hope <[email protected]> wrote: > For portability I would suggest starting to move towards the GError > scheme provided by glib (also used by gmime). This is a somewhat major > effort though since ensuring that error propagation is done right [0] is > somewhat tricky. It provides more or less the same functionality as > exceptions do in C++. > > There is also the problem of having to change the API - one way to avoid > that is to create wrappers that behave like the old API, but don't > handle errors that good. This requires the addition of addiontal _error > variations of the current set of functions. It will be a mess. > > [0] https://developer.gnome.org/glib/stable/glib-Error-Reporting.html
Here's a quick mockup of how that could look. Cheers, Gaute
From eb49e311e312a5c9510ca24dec24ad1c60aedee9 Mon Sep 17 00:00:00 2001 From: Gaute Hope <[email protected]> Date: Thu, 21 Aug 2014 10:56:57 +0200 Subject: [PATCH] mockup: Illustration of GError for error reporting --- lib/database.cc | 23 +++++++++++++++++++++-- lib/notmuch.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 9c0952a..085152f 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -42,6 +42,8 @@ typedef struct { const char *prefix; } prefix_t; +GQuark notmuch_error_quark; + #define NOTMUCH_DATABASE_VERSION 2 #define STRINGIFY(s) _SUB_STRINGIFY(s) @@ -367,16 +369,28 @@ _message_id_compressed (void *ctx, const char *message_id) return compressed; } +/* deprecated wrapper */ notmuch_status_t notmuch_database_find_message (notmuch_database_t *notmuch, const char *message_id, notmuch_message_t **message_ret) { + return notmuch_database_find_message_err (notmuch, message_id, message_ret, NULL); +} + +notmuch_status_t +notmuch_database_find_message_err (notmuch_database_t *notmuch, + const char *message_id, + notmuch_message_t **message_ret, + GError **err) +{ notmuch_private_status_t status; unsigned int doc_id; - if (message_ret == NULL) - return NOTMUCH_STATUS_NULL_POINTER; + if (message_ret == NULL) { + g_set_error (err, NOTMUCH_ERROR, NOTMUCH_STATUS_NULL_POINTER, notmuch_status_to_string (NOTMUCH_STATUS_NULL_POINTER)); + return NOTMUCH_STATUS_NULL_POINTER; + } if (strlen (message_id) > NOTMUCH_MESSAGE_ID_MAX) message_id = _message_id_compressed (notmuch, message_id); @@ -633,6 +647,11 @@ notmuch_database_open (const char *path, unsigned int i, version; static int initialized = 0; + /* Initialize GError system */ + if (! initialized) { + notmuch_error_quark = g_quark_from_static_string ("notmuch"); + } + if (path == NULL) { fprintf (stderr, "Error: Cannot open a database for a NULL path.\n"); status = NOTMUCH_STATUS_NULL_POINTER; diff --git a/lib/notmuch.h b/lib/notmuch.h index 3c5ec98..af28e09 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -42,6 +42,7 @@ NOTMUCH_BEGIN_DECLS #include <time.h> +#include <glib.h> #ifndef FALSE #define FALSE 0 @@ -159,6 +160,12 @@ typedef enum _notmuch_status { * The operation is not supported. */ NOTMUCH_STATUS_UNSUPPORTED_OPERATION, + + /* An Xapian::DatabaseModifiedError has occurred, all decendants of + * database are invalid and the database must be reopened. + */ + NOTMUCH_STATUS_XAPIAN_DATABASE_MODIFIED_ERROR, + /** * Not an actual status value. Just a way to find out how many * valid status values there are. @@ -166,6 +173,18 @@ typedef enum _notmuch_status { NOTMUCH_STATUS_LAST_STATUS } notmuch_status_t; + +/* errors */ +extern GQuark notmuch_error_quark; + + +/** + * NOTMUCH_ERROR: + * + * The Notmuch error domain GQuark value. + **/ +#define NOTMUCH_ERROR notmuch_error_quark + /** * Get a string representation of a notmuch_status_t value. * @@ -554,6 +573,35 @@ notmuch_database_find_message (notmuch_database_t *database, notmuch_message_t **message); /** + * Find a message with the given message_id. + * + * If a message with the given message_id is found then, on successful return + * (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to a message + * object. The caller should call notmuch_message_destroy when done with the + * message. + * + * On any failure or when the message is not found, this function initializes + * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the + * caller is supposed to check '*message' for NULL to find out whether the + * message with the given message_id was found. + * + * Return value: + * + * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'. + * + * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL + * + * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating message object + * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred + */ +notmuch_status_t +notmuch_database_find_message_err (notmuch_database_t *database, + const char *message_id, + notmuch_message_t **message, + GError **err); + +/** * Find a message with the given filename. * * If the database contains a message with the given filename then, on -- 2.0.4
_______________________________________________ notmuch mailing list [email protected] http://notmuchmail.org/mailman/listinfo/notmuch
