[PATCH 2/8] lib: add status return to _notmuch_message_ensure_metadata

Subject: [PATCH 2/8] lib: add status return to _notmuch_message_ensure_metadata

Date: Sat, 18 Feb 2017 10:45:45 -0400

To: notmuch@notmuchmail.org

Cc:

From: David Bremner


This is currently silently ignored everywhere, but that's not much
worse than crashing with an uncaught (and maybe uncatchable)
exception.
---
 lib/message.cc | 135 ++++++++++++++++++++++++++++++---------------------------
 1 file changed, 72 insertions(+), 63 deletions(-)

diff --git a/lib/message.cc b/lib/message.cc
index 9455b11d..916dd441 100644
--- a/lib/message.cc
+++ b/lib/message.cc
@@ -310,7 +310,7 @@ _notmuch_message_get_term (notmuch_message_t *message,
     return value;
 }
 
-static void
+static notmuch_private_status_t
 _notmuch_message_ensure_metadata (notmuch_message_t *message)
 {
     Xapian::TermIterator i, end;
@@ -328,72 +328,81 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message)
      * one field of the message object is actually used, it's a huge
      * win as more fields are used. */
 
-    i = message->doc.termlist_begin ();
-    end = message->doc.termlist_end ();
-
-    /* Get thread */
-    if (!message->thread_id)
-	message->thread_id =
-	    _notmuch_message_get_term (message, i, end, thread_prefix);
-
-    /* Get tags */
-    assert (strcmp (thread_prefix, tag_prefix) < 0);
-    if (!message->tag_list) {
-	message->tag_list =
-	    _notmuch_database_get_terms_with_prefix (message, i, end,
-						     tag_prefix);
-	_notmuch_string_list_sort (message->tag_list);
-    }
+    try {
+	i = message->doc.termlist_begin ();
+	end = message->doc.termlist_end ();
+
+	/* Get thread */
+	if (!message->thread_id)
+	    message->thread_id =
+		_notmuch_message_get_term (message, i, end, thread_prefix);
+
+	/* Get tags */
+	assert (strcmp (thread_prefix, tag_prefix) < 0);
+	if (!message->tag_list) {
+	    message->tag_list =
+		_notmuch_database_get_terms_with_prefix (message, i, end,
+							 tag_prefix);
+	    _notmuch_string_list_sort (message->tag_list);
+	}
 
-    /* Get id */
-    assert (strcmp (tag_prefix, id_prefix) < 0);
-    if (!message->message_id)
-	message->message_id =
-	    _notmuch_message_get_term (message, i, end, id_prefix);
-
-    /* Get document type */
-    assert (strcmp (id_prefix, type_prefix) < 0);
-    if (! NOTMUCH_TEST_BIT (message->lazy_flags, NOTMUCH_MESSAGE_FLAG_GHOST)) {
-	i.skip_to (type_prefix);
-	/* "T" is the prefix "type" fields.  See
+	/* Get id */
+	assert (strcmp (tag_prefix, id_prefix) < 0);
+	if (!message->message_id)
+	    message->message_id =
+		_notmuch_message_get_term (message, i, end, id_prefix);
+
+	/* Get document type */
+	assert (strcmp (id_prefix, type_prefix) < 0);
+	if (! NOTMUCH_TEST_BIT (message->lazy_flags, NOTMUCH_MESSAGE_FLAG_GHOST)) {
+	    i.skip_to (type_prefix);
+	    /* "T" is the prefix "type" fields.  See
 	 * BOOLEAN_PREFIX_INTERNAL. */
-	if (*i == "Tmail")
-	    NOTMUCH_CLEAR_BIT (&message->flags, NOTMUCH_MESSAGE_FLAG_GHOST);
-	else if (*i == "Tghost")
-	    NOTMUCH_SET_BIT (&message->flags, NOTMUCH_MESSAGE_FLAG_GHOST);
-	else
-	    INTERNAL_ERROR ("Message without type term");
-	NOTMUCH_SET_BIT (&message->lazy_flags, NOTMUCH_MESSAGE_FLAG_GHOST);
-    }
-
-    /* Get filename list.  Here we get only the terms.  We lazily
-     * expand them to full file names when needed in
-     * _notmuch_message_ensure_filename_list. */
-    assert (strcmp (type_prefix, filename_prefix) < 0);
-    if (!message->filename_term_list && !message->filename_list)
-	message->filename_term_list =
-	    _notmuch_database_get_terms_with_prefix (message, i, end,
-						     filename_prefix);
-
-
-    /* Get property terms. Mimic the setup with filenames above */
-    assert (strcmp (filename_prefix, property_prefix) < 0);
-    if (!message->property_map && !message->property_term_list)
-	message->property_term_list =
-	    _notmuch_database_get_terms_with_prefix (message, i, end,
-						     property_prefix);
-
-    /* Get reply to */
-    assert (strcmp (property_prefix, replyto_prefix) < 0);
-    if (!message->in_reply_to)
-	message->in_reply_to =
-	    _notmuch_message_get_term (message, i, end, replyto_prefix);
+	    if (*i == "Tmail")
+		NOTMUCH_CLEAR_BIT (&message->flags, NOTMUCH_MESSAGE_FLAG_GHOST);
+	    else if (*i == "Tghost")
+		NOTMUCH_SET_BIT (&message->flags, NOTMUCH_MESSAGE_FLAG_GHOST);
+	    else
+		INTERNAL_ERROR ("Message without type term");
+	    NOTMUCH_SET_BIT (&message->lazy_flags, NOTMUCH_MESSAGE_FLAG_GHOST);
+	}
 
+	/* Get filename list.  Here we get only the terms.  We lazily
+	 * expand them to full file names when needed in
+	 * _notmuch_message_ensure_filename_list. */
+	assert (strcmp (type_prefix, filename_prefix) < 0);
+	if (!message->filename_term_list && !message->filename_list)
+	    message->filename_term_list =
+		_notmuch_database_get_terms_with_prefix (message, i, end,
+							 filename_prefix);
+
+
+	/* Get property terms. Mimic the setup with filenames above */
+	assert (strcmp (filename_prefix, property_prefix) < 0);
+	if (!message->property_map && !message->property_term_list)
+	    message->property_term_list =
+		_notmuch_database_get_terms_with_prefix (message, i, end,
+							 property_prefix);
+
+	/* Get reply to */
+	assert (strcmp (property_prefix, replyto_prefix) < 0);
+	if (!message->in_reply_to)
+	    message->in_reply_to =
+		_notmuch_message_get_term (message, i, end, replyto_prefix);
+
+
+	/* It's perfectly valid for a message to have no In-Reply-To
+	 * header. For these cases, we return an empty string. */
+	if (!message->in_reply_to)
+	    message->in_reply_to = talloc_strdup (message, "");
+    } catch (const Xapian::Error &error) {
+	_notmuch_database_log(_notmuch_message_database (message), "A Xapian exception occurred fetching message metadata\n",
+		 error.get_msg().c_str());
+	message->notmuch->exception_reported = TRUE;
+	return NOTMUCH_PRIVATE_STATUS_XAPIAN_EXCEPTION;
+    }
 
-    /* It's perfectly valid for a message to have no In-Reply-To
-     * header. For these cases, we return an empty string. */
-    if (!message->in_reply_to)
-	message->in_reply_to = talloc_strdup (message, "");
+    return NOTMUCH_PRIVATE_STATUS_SUCCESS;
 }
 
 void
-- 
2.11.0


Thread: