aboutsummaryrefslogtreecommitdiff
path: root/lib/query.cc
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2025-07-07 14:27:06 +0200
committerDavid Bremner <david@tethera.net>2025-07-24 07:30:58 -0300
commitf375ea1add121c428f261473512831a169dfe335 (patch)
treee294f60da65ba4f76e9f53d2afcd118b6b157cb6 /lib/query.cc
parent4547ae5aa8fc7fd5d05da801c9fa9c055d39636f (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/query.cc')
-rw-r--r--lib/query.cc13
1 files changed, 10 insertions, 3 deletions
diff --git a/lib/query.cc b/lib/query.cc
index 1c60c122..976fe76d 100644
--- a/lib/query.cc
+++ b/lib/query.cc
@@ -371,6 +371,7 @@ _notmuch_query_search_documents (notmuch_query_t *query,
messages->base.is_of_list_type = false;
messages->base.iterator = NULL;
+ messages->base.status = NOTMUCH_STATUS_SUCCESS;
messages->notmuch = notmuch;
new (&messages->iterator) Xapian::MSetIterator ();
new (&messages->iterator_end) Xapian::MSetIterator ();
@@ -509,9 +510,15 @@ _notmuch_mset_messages_get (notmuch_messages_t *messages)
mset_messages->notmuch, doc_id,
&status);
- if (message == NULL &&
- status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
- INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
+ if (message == NULL) {
+ if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND) {
+ INTERNAL_ERROR ("a messages iterator contains a non-existent document ID.\n");
+ } else if (status != NOTMUCH_PRIVATE_STATUS_SUCCESS) {
+ messages->status = COERCE_STATUS (status, "error creating a message");
+ return NULL;
+ }
+
+ INTERNAL_ERROR ("NULL message with no error code\n");
}
if (messages->excluded_doc_ids &&