lib/message: catch exceptions in _n_m_add_term

Some code movement is needed to make sure the cache is only
invalidated when the Xapian operation succeeds.
This commit is contained in:
David Bremner 2022-05-23 20:38:55 -03:00
parent 2707c06a0f
commit f48d2e2ff8
2 changed files with 34 additions and 10 deletions

View file

@ -1490,24 +1490,30 @@ _notmuch_message_add_term (notmuch_message_t *message,
{ {
char *term; char *term;
notmuch_private_status_t status = NOTMUCH_PRIVATE_STATUS_SUCCESS;
if (value == NULL) if (value == NULL)
return NOTMUCH_PRIVATE_STATUS_NULL_POINTER; return NOTMUCH_PRIVATE_STATUS_NULL_POINTER;
term = talloc_asprintf (message, "%s%s", term = talloc_asprintf (message, "%s%s",
_find_prefix (prefix_name), value); _find_prefix (prefix_name), value);
if (strlen (term) > NOTMUCH_TERM_MAX) {
status = NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG;
goto DONE;
}
if (strlen (term) > NOTMUCH_TERM_MAX) try {
return NOTMUCH_PRIVATE_STATUS_TERM_TOO_LONG; message->doc.add_term (term, 0);
message->modified = true;
message->doc.add_term (term, 0); _notmuch_message_invalidate_metadata (message, prefix_name);
message->modified = true; } catch (Xapian::Error &error) {
LOG_XAPIAN_EXCEPTION (message, error);
status = NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
}
DONE:
talloc_free (term); talloc_free (term);
return status;
_notmuch_message_invalidate_metadata (message, prefix_name);
return NOTMUCH_PRIVATE_STATUS_SUCCESS;
} }
/* Parse 'text' and add a term to 'message' for each parsed word. Each /* Parse 'text' and add a term to 'message' for each parsed word. Each
@ -1571,11 +1577,12 @@ _notmuch_message_remove_term (notmuch_message_t *message,
try { try {
message->doc.remove_term (term); message->doc.remove_term (term);
message->modified = true; message->modified = true;
} catch (const Xapian::InvalidArgumentError) { } catch (const Xapian::InvalidArgumentError &error) {
/* We'll let the philosophers try to wrestle with the /* We'll let the philosophers try to wrestle with the
* question of whether failing to remove that which was not * question of whether failing to remove that which was not
* there in the first place is failure. For us, we'll silently * there in the first place is failure. For us, we'll silently
* consider it all good. */ * consider it all good. */
LOG_XAPIAN_EXCEPTION (message, error);
} }
talloc_free (term); talloc_free (term);

View file

@ -307,6 +307,23 @@ cat <<EOF > EXPECTED
EOF EOF
test_expect_equal_file EXPECTED OUTPUT test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "_notmuch_message_add_term catches exceptions"
cat c_head0 - c_tail <<'EOF' | test_private_C ${MAIL_DIR}
{
notmuch_private_status_t status;
/* This relies on Xapian throwing an exception for adding empty terms */
status = _notmuch_message_add_term (message, "body", "");
printf("%d\n%d\n", message != NULL, status != NOTMUCH_STATUS_SUCCESS );
}
EOF
cat <<EOF > EXPECTED
== stdout ==
1
1
== stderr ==
EOF
test_expect_equal_file EXPECTED OUTPUT
test_begin_subtest "Handle removing all tags with closed db" test_begin_subtest "Handle removing all tags with closed db"
cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
{ {