mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-25 12:28:09 +01:00
lib: handle DatabaseModifiedError in _n_message_ensure_metadata
The retries are hardcoded to a small number, and error handling aborts than propagating errors from notmuch_database_reopen. These are both somewhat justified by the assumption that most things that can go wrong in Xapian::Database::reopen are rare and fatal. Here's the brief discussion with Xapian upstream: 24-02-2017 08:12:57 < bremner> any intuition about how likely Xapian::Database::reopen is to fail? I'm catching a DatabaseModifiedError somewhere where handling any further errors is tricky, and wondering about treating a failed reopen as as "the impossible happened, stopping" 24-02-2017 16:22:34 < olly> bremner: there should not be much scope for failure - stuff like out of memory or disk errors, which are probably a good enough excuse to stop
This commit is contained in:
parent
e17a914b77
commit
e0b22c139c
2 changed files with 85 additions and 64 deletions
|
@ -49,6 +49,9 @@ struct visible _notmuch_message {
|
|||
/* Message document modified since last sync */
|
||||
notmuch_bool_t modified;
|
||||
|
||||
/* last view of database the struct is synced with */
|
||||
unsigned long last_view;
|
||||
|
||||
Xapian::Document doc;
|
||||
Xapian::termcount termpos;
|
||||
};
|
||||
|
@ -110,6 +113,9 @@ _notmuch_message_create_for_document (const void *talloc_owner,
|
|||
message->flags = 0;
|
||||
message->lazy_flags = 0;
|
||||
|
||||
/* the message is initially not synchronized with Xapian */
|
||||
message->last_view = 0;
|
||||
|
||||
/* Each of these will be lazily created as needed. */
|
||||
message->message_id = NULL;
|
||||
message->thread_id = NULL;
|
||||
|
@ -314,6 +320,7 @@ static void
|
|||
_notmuch_message_ensure_metadata (notmuch_message_t *message)
|
||||
{
|
||||
Xapian::TermIterator i, end;
|
||||
|
||||
const char *thread_prefix = _find_prefix ("thread"),
|
||||
*tag_prefix = _find_prefix ("tag"),
|
||||
*id_prefix = _find_prefix ("id"),
|
||||
|
@ -327,7 +334,8 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message)
|
|||
* slightly more costly than looking up individual fields if only
|
||||
* one field of the message object is actually used, it's a huge
|
||||
* win as more fields are used. */
|
||||
|
||||
for (int count=0; count < 3; count++) {
|
||||
try {
|
||||
i = message->doc.termlist_begin ();
|
||||
end = message->doc.termlist_end ();
|
||||
|
||||
|
@ -394,6 +402,20 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message)
|
|||
* header. For these cases, we return an empty string. */
|
||||
if (!message->in_reply_to)
|
||||
message->in_reply_to = talloc_strdup (message, "");
|
||||
|
||||
/* all the way without an exception */
|
||||
break;
|
||||
} catch (const Xapian::DatabaseModifiedError &error) {
|
||||
notmuch_status_t status = _notmuch_database_reopen (message->notmuch);
|
||||
if (status != NOTMUCH_STATUS_SUCCESS)
|
||||
INTERNAL_ERROR ("unhandled error from notmuch_database_reopen: %s\n",
|
||||
notmuch_status_to_string (status));
|
||||
} catch (const Xapian::Error &error) {
|
||||
INTERNAL_ERROR ("A Xapian exception occurred fetching message metadata: %s\n",
|
||||
error.get_msg().c_str());
|
||||
}
|
||||
}
|
||||
message->last_view = message->notmuch->view;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -6,7 +6,6 @@ test_description="DatabaseModifiedError handling"
|
|||
add_email_corpus
|
||||
|
||||
test_begin_subtest "catching DatabaseModifiedError in _notmuch_message_ensure_metadata"
|
||||
test_subtest_known_broken
|
||||
# it seems to need to be an early document to trigger the exception
|
||||
first_id=$(notmuch search --output=messages '*'| head -1 | sed s/^id://)
|
||||
|
||||
|
|
Loading…
Reference in a new issue