lib/message-property: catch xapian exceptions

Since libnotmuch exposes a C interface there's no way for clients to
catch this.
Inspired by what's done for tags (see notmuch_message_remove_tag).
This commit is contained in:
Kevin Boulain 2023-03-29 18:19:58 +02:00 committed by David Bremner
parent c810312e24
commit 568f6bc3c2
2 changed files with 30 additions and 8 deletions

View file

@ -25,6 +25,20 @@
#include "database-private.h" #include "database-private.h"
#include "message-private.h" #include "message-private.h"
#define LOG_XAPIAN_EXCEPTION(message, error) _log_xapian_exception (__location__, message, error)
static void
_log_xapian_exception (const char *where, notmuch_message_t *message, const Xapian::Error error)
{
notmuch_database_t *notmuch = notmuch_message_get_database (message);
_notmuch_database_log (notmuch,
"A Xapian exception occurred at %s: %s\n",
where,
error.get_msg ().c_str ());
notmuch->exception_reported = true;
}
notmuch_status_t notmuch_status_t
notmuch_message_get_property (notmuch_message_t *message, const char *key, const char **value) notmuch_message_get_property (notmuch_message_t *message, const char *key, const char **value)
{ {
@ -83,10 +97,15 @@ _notmuch_message_modify_property (notmuch_message_t *message, const char *key, c
term = talloc_asprintf (message, "%s=%s", key, value); term = talloc_asprintf (message, "%s=%s", key, value);
if (delete_it) try {
private_status = _notmuch_message_remove_term (message, "property", term); if (delete_it)
else private_status = _notmuch_message_remove_term (message, "property", term);
private_status = _notmuch_message_add_term (message, "property", term); else
private_status = _notmuch_message_add_term (message, "property", term);
} catch (Xapian::Error &error) {
LOG_XAPIAN_EXCEPTION (message, error);
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
if (private_status) if (private_status)
return COERCE_STATUS (private_status, return COERCE_STATUS (private_status,
@ -130,8 +149,13 @@ _notmuch_message_remove_all_properties (notmuch_message_t *message, const char *
else else
term_prefix = _find_prefix ("property"); term_prefix = _find_prefix ("property");
/* XXX better error reporting ? */ try {
_notmuch_message_remove_terms (message, term_prefix); /* XXX better error reporting ? */
_notmuch_message_remove_terms (message, term_prefix);
} catch (Xapian::Error &error) {
LOG_XAPIAN_EXCEPTION (message, error);
return NOTMUCH_STATUS_XAPIAN_EXCEPTION;
}
return NOTMUCH_STATUS_SUCCESS; return NOTMUCH_STATUS_SUCCESS;
} }

View file

@ -363,7 +363,6 @@ EOF
test_expect_equal_file /dev/null OUTPUT test_expect_equal_file /dev/null OUTPUT
test_begin_subtest "edit property on removed message without uncaught exception" test_begin_subtest "edit property on removed message without uncaught exception"
test_subtest_known_broken
cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
EXPECT0(notmuch_database_remove_message (db, notmuch_message_get_filename (message))); EXPECT0(notmuch_database_remove_message (db, notmuch_message_get_filename (message)));
stat = notmuch_message_remove_property (message, "example", "example"); stat = notmuch_message_remove_property (message, "example", "example");
@ -380,7 +379,6 @@ test_expect_equal_file EXPECTED OUTPUT
add_email_corpus add_email_corpus
test_begin_subtest "remove all properties on removed message without uncaught exception" test_begin_subtest "remove all properties on removed message without uncaught exception"
test_subtest_known_broken
cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR} cat c_head - c_tail <<'EOF' | test_C ${MAIL_DIR}
EXPECT0(notmuch_database_remove_message (db, notmuch_message_get_filename (message))); EXPECT0(notmuch_database_remove_message (db, notmuch_message_get_filename (message)));
stat = notmuch_message_remove_all_properties_with_prefix (message, ""); stat = notmuch_message_remove_all_properties_with_prefix (message, "");