--- /dev/null
+Return-Path: <polatel@gmail.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id B72A4431FB6\r
+ for <notmuch@notmuchmail.org>; Mon, 3 Oct 2011 22:06:31 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Amavis-Alert: BAD HEADER SECTION, Duplicate header field: "References"\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 1.7\r
+X-Spam-Level: *\r
+X-Spam-Status: No, score=1.7 tagged_above=-999 required=5\r
+ tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+ FREEMAIL_FROM=0.001, FREEMAIL_REPLY=2.499, RCVD_IN_DNSWL_LOW=-0.7]\r
+ autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id sHIRwsbxYxp7 for <notmuch@notmuchmail.org>;\r
+ Mon, 3 Oct 2011 22:06:29 -0700 (PDT)\r
+Received: from mail-bw0-f53.google.com (mail-bw0-f53.google.com\r
+ [209.85.214.53]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+ (No client certificate requested)\r
+ by olra.theworths.org (Postfix) with ESMTPS id 84C8C429E21\r
+ for <notmuch@notmuchmail.org>; Mon, 3 Oct 2011 22:06:29 -0700 (PDT)\r
+Received: by mail-bw0-f53.google.com with SMTP id zt12so224537bkb.26\r
+ for <notmuch@notmuchmail.org>; Mon, 03 Oct 2011 22:06:29 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma;\r
+ h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references\r
+ :in-reply-to:references:organization;\r
+ bh=86KHwNgRSa0Anrzm0ZDo7mMdTnrNDhLYpZcl8oaqvWY=;\r
+ b=nZ/s01tco/0hD40gfPA0PE3duBp31mn3m4LzmJGKVbB3+Ia7fRvweoIaF0BjBzc5M2\r
+ rE81m2GM6kBGDY8ZRl3M7yMkWnr/jzyMRqUfGdpTzfVBAtycIkLV75zRexwsjvIS2Jlr\r
+ TfddUdt+kwUA8Ody8wPBWAiuaBZqJ8K0dJo9o=\r
+Received: by 10.223.29.203 with SMTP id r11mr1137448fac.10.1317704789016;\r
+ Mon, 03 Oct 2011 22:06:29 -0700 (PDT)\r
+Received: from localhost ([88.236.39.101])\r
+ by mx.google.com with ESMTPS id f25sm24008333faf.7.2011.10.03.22.06.27\r
+ (version=TLSv1/SSLv3 cipher=OTHER);\r
+ Mon, 03 Oct 2011 22:06:28 -0700 (PDT)\r
+From: Ali Polatel <polatel@gmail.com>\r
+To: David Bremner <david@tethera.net>\r
+Subject: [PATCH v3 2/2] lib: make find_message{,by_filename) report errors\r
+Date: Tue, 4 Oct 2011 08:06:09 +0300\r
+Message-Id:\r
+ <02a30767116ad8abcbd0a3351f2e4d43bbbd655f.1317704225.git.alip@exherbo.org>\r
+X-Mailer: git-send-email 1.7.6.1\r
+In-Reply-To: <cover.1317704225.git.alip@exherbo.org>\r
+References: <20111004050046.GA6048@hayalet>\r
+ <cover.1317704225.git.alip@exherbo.org>\r
+In-Reply-To: <cover.1317704225.git.alip@exherbo.org>\r
+References: <cover.1317704225.git.alip@exherbo.org>\r
+Organization: Pink Floyd\r
+Cc: Ali Polatel <alip@exherbo.org>,\r
+ Notmuch Mailing List <notmuch@notmuchmail.org>,\r
+ Austin Clements <amdragon@MIT.EDU>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Tue, 04 Oct 2011 05:06:31 -0000\r
+\r
+From: Ali Polatel <alip@exherbo.org>\r
+\r
+Previously, the functions notmuch_database_find_message() and\r
+notmuch_database_find_message_by_filename() functions did not properly\r
+report error condition to the library user.\r
+\r
+For more information, read the thread on the notmuch mailing list\r
+starting with my mail "id:871uv2unfd.fsf@gmail.com"\r
+\r
+Make these functions accept a pointer to 'notmuch_message_t' as argument\r
+and return notmuch_status_t which may be used to check for any error\r
+condition.\r
+\r
+restore: Modify for the new notmuch_database_find_message()\r
+new: Modify for the new notmuch_database_find_message_by_filename()\r
+---\r
+ lib/database.cc | 96 ++++++++++++++++++++++++++++++++++++-----------------\r
+ lib/message.cc | 8 +++--\r
+ lib/notmuch.h | 58 ++++++++++++++++++++++----------\r
+ notmuch-new.c | 4 ++-\r
+ notmuch-restore.c | 11 ++++--\r
+ 5 files changed, 120 insertions(+), 57 deletions(-)\r
+\r
+diff --git a/lib/database.cc b/lib/database.cc\r
+index d43e114..e77fd53 100644\r
+--- a/lib/database.cc\r
++++ b/lib/database.cc\r
+@@ -360,13 +360,17 @@ _message_id_compressed (void *ctx, const char *message_id)\r
+ return compressed;\r
+ }\r
+ \r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message (notmuch_database_t *notmuch,\r
+- const char *message_id)\r
++ const char *message_id,\r
++ notmuch_message_t **message_ret)\r
+ {\r
+ notmuch_private_status_t status;\r
+ unsigned int doc_id;\r
+ \r
++ if (message_ret == NULL)\r
++ return NOTMUCH_STATUS_NULL_POINTER;\r
++\r
+ if (strlen (message_id) > NOTMUCH_MESSAGE_ID_MAX)\r
+ message_id = _message_id_compressed (notmuch, message_id);\r
+ \r
+@@ -375,14 +379,21 @@ notmuch_database_find_message (notmuch_database_t *notmuch,\r
+ message_id, &doc_id);\r
+ \r
+ if (status == NOTMUCH_PRIVATE_STATUS_NO_DOCUMENT_FOUND)\r
+- return NULL;\r
++ *message_ret = NULL;\r
++ else {\r
++ *message_ret = _notmuch_message_create (notmuch, notmuch, doc_id,\r
++ NULL);\r
++ if (*message_ret == NULL)\r
++ return NOTMUCH_STATUS_OUT_OF_MEMORY;\r
++ }\r
+ \r
+- return _notmuch_message_create (notmuch, notmuch, doc_id, NULL);\r
++ return NOTMUCH_STATUS_SUCCESS;\r
+ } catch (const Xapian::Error &error) {\r
+ fprintf (stderr, "A Xapian exception occurred finding message: %s.\n",\r
+ error.get_msg().c_str());\r
+ notmuch->exception_reported = TRUE;\r
+- return NULL;\r
++ *message_ret = NULL;\r
++ return NOTMUCH_STATUS_XAPIAN_EXCEPTION;\r
+ }\r
+ }\r
+ \r
+@@ -1311,7 +1322,9 @@ _get_metadata_thread_id_key (void *ctx, const char *message_id)\r
+ \r
+ /* Find the thread ID to which the message with 'message_id' belongs.\r
+ *\r
+- * Always returns a newly talloced string belonging to 'ctx'.\r
++ * Note: 'thread_id_ret' must not be NULL!\r
++ * On success '*thread_id_ret' is set to a newly talloced string belonging to\r
++ * 'ctx'.\r
+ *\r
+ * Note: If there is no message in the database with the given\r
+ * 'message_id' then a new thread_id will be allocated for this\r
+@@ -1319,25 +1332,30 @@ _get_metadata_thread_id_key (void *ctx, const char *message_id)\r
+ * thread ID can be looked up if the message is added to the database\r
+ * later).\r
+ */\r
+-static const char *\r
++static notmuch_status_t\r
+ _resolve_message_id_to_thread_id (notmuch_database_t *notmuch,\r
+ void *ctx,\r
+- const char *message_id)\r
++ const char *message_id,\r
++ const char **thread_id_ret)\r
+ {\r
++ notmuch_status_t status;\r
+ notmuch_message_t *message;\r
+ string thread_id_string;\r
+- const char *thread_id;\r
+ char *metadata_key;\r
+ Xapian::WritableDatabase *db;\r
+ \r
+- message = notmuch_database_find_message (notmuch, message_id);\r
++ status = notmuch_database_find_message (notmuch, message_id, &message);\r
++\r
++ if (status)\r
++ return status;\r
+ \r
+ if (message) {\r
+- thread_id = talloc_steal (ctx, notmuch_message_get_thread_id (message));\r
++ *thread_id_ret = talloc_steal (ctx,\r
++ notmuch_message_get_thread_id (message));\r
+ \r
+ notmuch_message_destroy (message);\r
+ \r
+- return thread_id;\r
++ return NOTMUCH_STATUS_SUCCESS;\r
+ }\r
+ \r
+ /* Message has not been seen yet.\r
+@@ -1351,15 +1369,16 @@ _resolve_message_id_to_thread_id (notmuch_database_t *notmuch,\r
+ thread_id_string = notmuch->xapian_db->get_metadata (metadata_key);\r
+ \r
+ if (thread_id_string.empty()) {\r
+- thread_id = _notmuch_database_generate_thread_id (notmuch);\r
+- db->set_metadata (metadata_key, thread_id);\r
++ *thread_id_ret = talloc_strdup (ctx,\r
++ _notmuch_database_generate_thread_id (notmuch));\r
++ db->set_metadata (metadata_key, *thread_id_ret);\r
+ } else {\r
+- thread_id = thread_id_string.c_str();\r
++ *thread_id_ret = talloc_strdup (ctx, thread_id_string.c_str());\r
+ }\r
+ \r
+ talloc_free (metadata_key);\r
+ \r
+- return talloc_strdup (ctx, thread_id);\r
++ return NOTMUCH_STATUS_SUCCESS;\r
+ }\r
+ \r
+ static notmuch_status_t\r
+@@ -1446,9 +1465,12 @@ _notmuch_database_link_message_to_parents (notmuch_database_t *notmuch,\r
+ _notmuch_message_add_term (message, "reference",\r
+ parent_message_id);\r
+ \r
+- parent_thread_id = _resolve_message_id_to_thread_id (notmuch,\r
+- message,\r
+- parent_message_id);\r
++ ret = _resolve_message_id_to_thread_id (notmuch,\r
++ message,\r
++ parent_message_id,\r
++ &parent_thread_id);\r
++ if (ret)\r
++ goto DONE;\r
+ \r
+ if (*thread_id == NULL) {\r
+ *thread_id = talloc_strdup (message, parent_thread_id);\r
+@@ -1759,11 +1781,13 @@ notmuch_status_t\r
+ notmuch_database_remove_message (notmuch_database_t *notmuch,\r
+ const char *filename)\r
+ {\r
+- notmuch_message_t *message =\r
+- notmuch_database_find_message_by_filename (notmuch, filename);\r
+- notmuch_status_t status = NOTMUCH_STATUS_SUCCESS;\r
++ notmuch_status_t status;\r
++ notmuch_message_t *message;\r
+ \r
+- if (message) {\r
++ status = notmuch_database_find_message_by_filename (notmuch, filename,\r
++ &message);\r
++\r
++ if (status == NOTMUCH_STATUS_SUCCESS && message) {\r
+ status = _notmuch_message_remove_filename (message, filename);\r
+ if (status == NOTMUCH_STATUS_SUCCESS)\r
+ _notmuch_message_delete (message);\r
+@@ -1776,24 +1800,27 @@ notmuch_database_remove_message (notmuch_database_t *notmuch,\r
+ return status;\r
+ }\r
+ \r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,\r
+- const char *filename)\r
++ const char *filename,\r
++ notmuch_message_t **message_ret)\r
+ {\r
+ void *local;\r
+ const char *prefix = _find_prefix ("file-direntry");\r
+ char *direntry, *term;\r
+ Xapian::PostingIterator i, end;\r
+- notmuch_message_t *message = NULL;\r
+ notmuch_status_t status;\r
+ \r
++ if (message_ret == NULL)\r
++ return NOTMUCH_STATUS_NULL_POINTER;\r
++\r
+ local = talloc_new (notmuch);\r
+ \r
+ try {\r
+ status = _notmuch_database_filename_to_direntry (local, notmuch,\r
+ filename, &direntry);\r
+ if (status)\r
+- return NULL;\r
++ goto DONE;\r
+ \r
+ term = talloc_asprintf (local, "%s%s", prefix, direntry);\r
+ \r
+@@ -1802,19 +1829,26 @@ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,\r
+ if (i != end) {\r
+ notmuch_private_status_t private_status;\r
+ \r
+- message = _notmuch_message_create (notmuch, notmuch,\r
+- *i, &private_status);\r
++ *message_ret = _notmuch_message_create (notmuch, notmuch, *i,\r
++ &private_status);\r
++ if (*message_ret == NULL)\r
++ status = NOTMUCH_STATUS_OUT_OF_MEMORY;\r
+ }\r
+ } catch (const Xapian::Error &error) {\r
+ fprintf (stderr, "Error: A Xapian exception occurred finding message by filename: %s\n",\r
+ error.get_msg().c_str());\r
+ notmuch->exception_reported = TRUE;\r
+- message = NULL;\r
++ status = NOTMUCH_STATUS_XAPIAN_EXCEPTION;\r
+ }\r
+ \r
++ DONE:\r
+ talloc_free (local);\r
+ \r
+- return message;\r
++ if (status && *message_ret) {\r
++ notmuch_message_destroy (*message_ret);\r
++ *message_ret = NULL;\r
++ }\r
++ return status;\r
+ }\r
+ \r
+ notmuch_string_list_t *\r
+diff --git a/lib/message.cc b/lib/message.cc\r
+index 531d304..8f22e02 100644\r
+--- a/lib/message.cc\r
++++ b/lib/message.cc\r
+@@ -216,11 +216,13 @@ _notmuch_message_create_for_message_id (notmuch_database_t *notmuch,\r
+ unsigned int doc_id;\r
+ char *term;\r
+ \r
+- *status_ret = NOTMUCH_PRIVATE_STATUS_SUCCESS;\r
+-\r
+- message = notmuch_database_find_message (notmuch, message_id);\r
++ *status_ret = (notmuch_private_status_t) notmuch_database_find_message (notmuch,\r
++ message_id,\r
++ &message);\r
+ if (message)\r
+ return talloc_steal (notmuch, message);\r
++ else if (*status_ret)\r
++ return NULL;\r
+ \r
+ term = talloc_asprintf (NULL, "%s%s",\r
+ _find_prefix ("id"), message_id);\r
+diff --git a/lib/notmuch.h b/lib/notmuch.h\r
+index 6d7a99f..c4330e4 100644\r
+--- a/lib/notmuch.h\r
++++ b/lib/notmuch.h\r
+@@ -347,35 +347,57 @@ notmuch_database_remove_message (notmuch_database_t *database,\r
+ \r
+ /* Find a message with the given message_id.\r
+ *\r
+- * If the database contains a message with the given message_id, then\r
+- * a new notmuch_message_t object is returned. The caller should call\r
+- * notmuch_message_destroy when done with the message.\r
++ * If a message with the given message_id is found then, on successful return\r
++ * (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to a message\r
++ * object. The caller should call notmuch_message_destroy when done with the\r
++ * message.\r
+ *\r
+- * This function returns NULL in the following situations:\r
++ * On any failure or when the message is not found, this function initializes\r
++ * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the\r
++ * caller is supposed to check '*message' for NULL to find out whether the\r
++ * message with the given message_id was found.\r
+ *\r
+- * * No message is found with the given message_id\r
+- * * An out-of-memory situation occurs\r
+- * * A Xapian exception occurs\r
++ * Return value:\r
++ *\r
++ * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'.\r
++ *\r
++ * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL\r
++ *\r
++ * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating message object\r
++ *\r
++ * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred\r
+ */\r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message (notmuch_database_t *database,\r
+- const char *message_id);\r
++ const char *message_id,\r
++ notmuch_message_t **message);\r
+ \r
+ /* Find a message with the given filename.\r
+ *\r
+- * If the database contains a message with the given filename, then a\r
+- * new notmuch_message_t object is returned. The caller should call \r
+- * notmuch_message_destroy when done with the message.\r
++ * If the database contains a message with the given filename then, on\r
++ * successful return (NOTMUCH_STATUS_SUCCESS) '*message' will be initialized to\r
++ * a message object. The caller should call notmuch_message_destroy when done\r
++ * with the message.\r
+ *\r
+- * This function returns NULL in the following situations:\r
++ * On any failure or when the message is not found, this function initializes\r
++ * '*message' to NULL. This means, when NOTMUCH_STATUS_SUCCESS is returned, the\r
++ * caller is supposed to check '*message' for NULL to find out whether the\r
++ * message with the given filename is found.\r
+ *\r
+- * * No message is found with the given filename\r
+- * * An out-of-memory situation occurs\r
+- * * A Xapian exception occurs\r
++ * Return value:\r
++ *\r
++ * NOTMUCH_STATUS_SUCCESS: Successful return, check '*message'\r
++ *\r
++ * NOTMUCH_STATUS_NULL_POINTER: The given 'message' argument is NULL\r
++ *\r
++ * NOTMUCH_STATUS_OUT_OF_MEMORY: Out of memory, creating the message object\r
++ *\r
++ * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred\r
+ */\r
+-notmuch_message_t *\r
++notmuch_status_t\r
+ notmuch_database_find_message_by_filename (notmuch_database_t *notmuch,\r
+- const char *filename);\r
++ const char *filename,\r
++ notmuch_message_t **message);\r
+ \r
+ /* Return a list of all tags found in the database.\r
+ *\r
+diff --git a/notmuch-new.c b/notmuch-new.c\r
+index e79593c..96a1e31 100644\r
+--- a/notmuch-new.c\r
++++ b/notmuch-new.c\r
+@@ -743,7 +743,9 @@ remove_filename (notmuch_database_t *notmuch,\r
+ status = notmuch_database_begin_atomic (notmuch);\r
+ if (status)\r
+ return status;\r
+- message = notmuch_database_find_message_by_filename (notmuch, path);\r
++ status = notmuch_database_find_message_by_filename (notmuch, path, &message);\r
++ if (status || message == NULL)\r
++ return status;\r
+ status = notmuch_database_remove_message (notmuch, path);\r
+ if (status == NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {\r
+ add_files_state->renamed_messages++;\r
+diff --git a/notmuch-restore.c b/notmuch-restore.c\r
+index f095f64..e4a5355 100644\r
+--- a/notmuch-restore.c\r
++++ b/notmuch-restore.c\r
+@@ -87,10 +87,13 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[])\r
+ file_tags = xstrndup (line + match[2].rm_so,\r
+ match[2].rm_eo - match[2].rm_so);\r
+ \r
+- message = notmuch_database_find_message (notmuch, message_id);\r
+- if (message == NULL) {\r
+- fprintf (stderr, "Warning: Cannot apply tags to missing message: %s\n",\r
+- message_id);\r
++ status = notmuch_database_find_message (notmuch, message_id, &message);\r
++ if (status || message == NULL) {\r
++ fprintf (stderr, "Warning: Cannot apply tags to %smessage: %s\n",\r
++ message ? "" : "missing ", message_id);\r
++ if (status)\r
++ fprintf (stderr, "%s\n",\r
++ notmuch_status_to_string(status));\r
+ goto NEXT_LINE;\r
+ }\r
+ \r
+-- \r
+1.7.6.1\r
+\r