From 9ef68f1444de981c47af06c948e3aa3ca5a377c8 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Sat, 24 Apr 2010 07:22:34 -0700 Subject: [PATCH] lib: Audit all notmuch_database call for Xapian exception handling. Our current approach is for top-level entry poitns in the library to have try/catch blocks that catch any Xapian exception and print a message. Add a few missing blocks and fix up the documentation. --- lib/database.cc | 96 ++++++++++++++++++++++++++++++++----------------- lib/notmuch.h | 15 ++++++-- 2 files changed, 77 insertions(+), 34 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 6842fafa..6afc8d93 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -341,13 +341,20 @@ notmuch_database_find_message (notmuch_database_t *notmuch, notmuch_private_status_t status; unsigned int doc_id; - status = _notmuch_database_find_unique_doc_id (notmuch, "id", - message_id, &doc_id); + try { + status = _notmuch_database_find_unique_doc_id (notmuch, "id", + message_id, &doc_id); - if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) - return NULL; + if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) + return NULL; - return _notmuch_message_create (notmuch, notmuch, doc_id, NULL); + return _notmuch_message_create (notmuch, notmuch, doc_id, NULL); + } catch (const Xapian::Error &error) { + fprintf (stderr, "A Xapian exception occurred finding message: %s.\n", + error.get_msg().c_str()); + notmuch->exception_reported = TRUE; + return NULL; + } } /* Advance 'str' past any whitespace or RFC 822 comments. A comment is @@ -1152,7 +1159,14 @@ notmuch_database_get_directory (notmuch_database_t *notmuch, { notmuch_status_t status; - return _notmuch_directory_create (notmuch, path, &status); + try { + return _notmuch_directory_create (notmuch, path, &status); + } catch (const Xapian::Error &error) { + fprintf (stderr, "A Xapian exception occurred getting directory: %s.\n", + error.get_msg().c_str()); + notmuch->exception_reported = TRUE; + return NULL; + } } static const char * @@ -1591,7 +1605,7 @@ notmuch_database_add_message (notmuch_database_t *notmuch, _notmuch_message_sync (message); } catch (const Xapian::Error &error) { fprintf (stderr, "A Xapian exception occurred adding message: %s.\n", - error.get_description().c_str()); + error.get_msg().c_str()); notmuch->exception_reported = TRUE; ret = NOTMUCH_STATUS_XAPIAN_EXCEPTION; goto DONE; @@ -1616,7 +1630,7 @@ notmuch_database_remove_message (notmuch_database_t *notmuch, const char *filename) { Xapian::WritableDatabase *db; - void *local = talloc_new (notmuch); + void *local; const char *prefix = _find_prefix ("file-direntry"); char *direntry, *term; Xapian::PostingIterator i, end; @@ -1627,37 +1641,47 @@ notmuch_database_remove_message (notmuch_database_t *notmuch, if (status) return status; + local = talloc_new (notmuch); + db = static_cast (notmuch->xapian_db); - status = _notmuch_database_filename_to_direntry (local, notmuch, - filename, &direntry); - if (status) - return status; + try { - term = talloc_asprintf (notmuch, "%s%s", prefix, direntry); + status = _notmuch_database_filename_to_direntry (local, notmuch, + filename, &direntry); + if (status) + return status; - find_doc_ids_for_term (notmuch, term, &i, &end); + term = talloc_asprintf (notmuch, "%s%s", prefix, direntry); - for ( ; i != end; i++) { - Xapian::TermIterator j; + find_doc_ids_for_term (notmuch, term, &i, &end); - document = find_document_for_doc_id (notmuch, *i); + for ( ; i != end; i++) { + Xapian::TermIterator j; - document.remove_term (term); + document = find_document_for_doc_id (notmuch, *i); - j = document.termlist_begin (); - j.skip_to (prefix); + document.remove_term (term); - /* Was this the last file-direntry in the message? */ - if (j == document.termlist_end () || - strncmp ((*j).c_str (), prefix, strlen (prefix))) - { - db->delete_document (document.get_docid ()); - status = NOTMUCH_STATUS_SUCCESS; - } else { - db->replace_document (document.get_docid (), document); - status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; + j = document.termlist_begin (); + j.skip_to (prefix); + + /* Was this the last file-direntry in the message? */ + if (j == document.termlist_end () || + strncmp ((*j).c_str (), prefix, strlen (prefix))) + { + db->delete_document (document.get_docid ()); + status = NOTMUCH_STATUS_SUCCESS; + } else { + db->replace_document (document.get_docid (), document); + status = NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID; + } } + } catch (const Xapian::Error &error) { + fprintf (stderr, "Error: A Xapian exception occurred removing message: %s\n", + error.get_msg().c_str()); + notmuch->exception_reported = TRUE; + status = NOTMUCH_STATUS_XAPIAN_EXCEPTION; } talloc_free (local); @@ -1703,7 +1727,15 @@ notmuch_tags_t * notmuch_database_get_all_tags (notmuch_database_t *db) { Xapian::TermIterator i, end; - i = db->xapian_db->allterms_begin(); - end = db->xapian_db->allterms_end(); - return _notmuch_convert_tags(db, i, end); + + try { + i = db->xapian_db->allterms_begin(); + end = db->xapian_db->allterms_end(); + return _notmuch_convert_tags(db, i, end); + } catch (const Xapian::Error &error) { + fprintf (stderr, "A Xapian exception occurred getting tags: %s.\n", + error.get_msg().c_str()); + db->exception_reported = TRUE; + return NULL; + } } diff --git a/lib/notmuch.h b/lib/notmuch.h index bae48a65..921b0fcf 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -219,6 +219,8 @@ notmuch_database_upgrade (notmuch_database_t *database, * Here, 'path' should be a path relative to the path of 'database' * (see notmuch_database_get_path), or else should be an absolute path * with initial components that match the path of 'database'. + * + * Can return NULL if a Xapian exception occurs. */ notmuch_directory_t * notmuch_database_get_directory (notmuch_database_t *database, @@ -246,6 +248,9 @@ notmuch_database_get_directory (notmuch_database_t *database, * * NOTMUCH_STATUS_SUCCESS: Message successfully added to database. * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred, + * message not added. + * * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: Message has the same message * ID as another message already in the database. The new * filename was successfully added to the message in the database @@ -280,6 +285,9 @@ notmuch_database_add_message (notmuch_database_t *database, * NOTMUCH_STATUS_SUCCESS: The last filename was removed and the * message was removed from the database. * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred, + * message not removed. + * * NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID: This filename was removed but * the message persists in the database with at least one other * filename. @@ -297,8 +305,11 @@ notmuch_database_remove_message (notmuch_database_t *database, * a new notmuch_message_t object is returned. The caller should call * notmuch_message_destroy when done with the message. * - * If no message is found with the given message_id or if an - * out-of-memory situation occurs, this function returns NULL. + * This function returns NULL in the following situations: + * + * * No message is found with the given message_id + * * An out-of-memory situation occurs + * * A Xapian exception occurs */ notmuch_message_t * notmuch_database_find_message (notmuch_database_t *database, -- 2.39.2