diff options
| author | Anton Khirnov <anton@khirnov.net> | 2025-07-07 14:27:06 +0200 |
|---|---|---|
| committer | David Bremner <david@tethera.net> | 2025-07-24 07:30:58 -0300 |
| commit | f375ea1add121c428f261473512831a169dfe335 (patch) | |
| tree | e294f60da65ba4f76e9f53d2afcd118b6b157cb6 /lib/notmuch.h | |
| parent | 4547ae5aa8fc7fd5d05da801c9fa9c055d39636f (diff) | |
lib: handle DatabaseModifiedError in _notmuch_message_create
If an open database is modified sufficiently by other callers, the open
instance becomes invalid and operations on it throw
DatabaseModifiedError. Per Xapian documentation, the caller is then
supposed to reopen the database and restart the query. This exception is
currently not handled in _notmuch_message_create(), leading to the
default handler abort()ing the process.
Catch this exception in _notmuch_message_create() and return an error
instead of crashing. Since the entire query becomes invalid - including
results that have already been read by the caller - this situation
cannot be handled by libnotmuch transparently. A new public function -
notmuch_messages_status() - is added to allow the callers to check
whether the messages iterator was exhausted or terminated early due to
a runtime error. This also allows memory allocation failure to be
signalled to the caller.
Amended-By: David Bremner <david@tethera.net>
[replace use of notmuch_messages_valid]
Diffstat (limited to 'lib/notmuch.h')
| -rw-r--r-- | lib/notmuch.h | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/lib/notmuch.h b/lib/notmuch.h index 937fa24e..e634e41f 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -233,6 +233,20 @@ typedef enum { */ NOTMUCH_STATUS_CLOSED_DATABASE, /** + * The iterator being examined has been exhausted and contains no more + * items. + */ + NOTMUCH_STATUS_ITERATOR_EXHAUSTED, + /** + * An operation that was being performed on the database has been + * invalidated while in progress, and must be re-executed. + * + * This will typically happen while iterating over query results and the + * underlying Xapian database is modified by another process so that the + * currently open version cannot be read anymore. + */ + NOTMUCH_STATUS_OPERATION_INVALIDATED, + /** * Not an actual status value. Just a way to find out how many * valid status values there are. */ @@ -1177,7 +1191,7 @@ notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out * return EXIT_FAILURE; * * for (; - * notmuch_messages_valid (messages); + * ! notmuch_messages_status (messages); * notmuch_messages_move_to_next (messages)) * { * message = notmuch_messages_get (messages); @@ -1185,6 +1199,9 @@ notmuch_query_search_threads_st (notmuch_query_t *query, notmuch_threads_t **out * notmuch_message_destroy (message); * } * + * if (notmuch_messages_status (messages) != NOTMUCH_STATUS_ITERATOR_EXHAUSTED) + * return EXIT_FAILURE; + * * notmuch_query_destroy (query); * * Note: If you are finished with a message before its containing @@ -1516,11 +1533,36 @@ notmuch_thread_destroy (notmuch_thread_t *thread); * * See the documentation of notmuch_query_search_messages for example * code showing how to iterate over a notmuch_messages_t object. + * + * Note that an iterator may become invalid either due to getting exhausted or + * due to a runtime error. Use notmuch_messages_status to distinguish + * between those cases. */ notmuch_bool_t notmuch_messages_valid (notmuch_messages_t *messages); /** + * Get the status of the given 'messages' iterator. + * + * Return value: + * + * NOTMUCH_STATUS_SUCCESS: The iterator is valid; notmuch_messages_get will + * return a valid object + * + * NOTMUCH_STATUS_ITERATOR_EXHAUSTED: All items have been read + * + * NOTMUCH_STATUS_OUT_OF_MEMORY: Iteration failed to allocate memory + * + * NOTMUCH_STATUS_OPERATION_INVALIDATED: Iteration was invalidated by the + * database. Re-open the database and try again. + * + * See the documentation of notmuch_query_search_messages for example + * code showing how to iterate over a notmuch_messages_t object. + */ +notmuch_status_t +notmuch_messages_status (notmuch_messages_t *messages); + +/** * Get the current message from 'messages' as a notmuch_message_t. * * Note: The returned message belongs to 'messages' and has a lifetime @@ -1540,8 +1582,8 @@ notmuch_messages_get (notmuch_messages_t *messages); * * If 'messages' is already pointing at the last message then the * iterator will be moved to a point just beyond that last message, - * (where notmuch_messages_valid will return FALSE and - * notmuch_messages_get will return NULL). + * (where notmuch_messages_status will return NOTMUCH_STATUS_ITERATOR_EXHAUSTED + * and notmuch_messages_get will return NULL). * * See the documentation of notmuch_query_search_messages for example * code showing how to iterate over a notmuch_messages_t object. @@ -1627,8 +1669,9 @@ notmuch_message_get_thread_id (notmuch_message_t *message); * will return NULL. * * If there are no replies to 'message', this function will return - * NULL. (Note that notmuch_messages_valid will accept that NULL - * value as legitimate, and simply return FALSE for it.) + * NULL. (Note that notmuch_messages_status will accept that NULL + * value as legitimate, and simply return NOTMUCH_STATUS_ITERATOR_EXHAUSTED + * for it.) * * This function also returns NULL if it triggers a Xapian exception. * |
