--- /dev/null
+Return-Path: <patricktotzke@googlemail.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 24044431FD0\r
+ for <notmuch@notmuchmail.org>; Sat, 23 Jul 2011 06:12:59 -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: -0.799\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.799 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, RCVD_IN_DNSWL_LOW=-0.7] 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 Vzw8zLDDSchG for <notmuch@notmuchmail.org>;\r
+ Sat, 23 Jul 2011 06:12:57 -0700 (PDT)\r
+Received: from mail-wy0-f181.google.com (mail-wy0-f181.google.com\r
+ [74.125.82.181]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+ (No client certificate requested)\r
+ by olra.theworths.org (Postfix) with ESMTPS id 9A710431FB6\r
+ for <notmuch@notmuchmail.org>; Sat, 23 Jul 2011 06:12:56 -0700 (PDT)\r
+Received: by wyh22 with SMTP id 22so2327529wyh.26\r
+ for <notmuch@notmuchmail.org>; Sat, 23 Jul 2011 06:12:55 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;\r
+ d=googlemail.com; s=gamma;\r
+ h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references\r
+ :in-reply-to:references;\r
+ bh=CjckEnceHtxo/0XwRNhzNET2z4Lhakgf+cqrhkCOV70=;\r
+ b=TQmTPYpn8qGK6NIl3Go2htxPv0KvYp9e8rkaR+B7fwk82RjKW2PTEemnJxqsDIwltM\r
+ odP2Rkx5jNA546ozIKn+xIGWGiE3B5nGFQCNjPisu8d9i8LDEwYrJEPQmqBzLug6WNuF\r
+ dmdDWObBKp4mTLycAisIPMW2LFZIymIAZnUyo=\r
+Received: by 10.227.6.18 with SMTP id 18mr2307644wbx.66.1311426775086;\r
+ Sat, 23 Jul 2011 06:12:55 -0700 (PDT)\r
+Received: from localhost (cpc1-sgyl2-0-0-cust47.sgyl.cable.virginmedia.com\r
+ [80.192.18.48])\r
+ by mx.google.com with ESMTPS id gb1sm2710367wbb.37.2011.07.23.06.12.53\r
+ (version=TLSv1/SSLv3 cipher=OTHER);\r
+ Sat, 23 Jul 2011 06:12:54 -0700 (PDT)\r
+From: pazz <patricktotzke@googlemail.com>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH] interpret Xapian errors from sdterr as exceptions\r
+Date: Sat, 23 Jul 2011 14:12:39 +0100\r
+Message-Id: <1311426759-32441-1-git-send-email-patricktotzke@gmail.com>\r
+X-Mailer: git-send-email 1.7.4.1\r
+In-Reply-To: <87r55o65yq.fsf@zancas.localnet>\r
+References: <87r55o65yq.fsf@zancas.localnet>\r
+In-Reply-To: <87r55o65yq.fsf@zancas.localnet>\r
+References: <87r55o65yq.fsf@zancas.localnet>\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: Sat, 23 Jul 2011 13:12:59 -0000\r
+\r
+This introduces globals.RaiseStderrErrors, a ContextManager\r
+that raises error messages printed by libnotmuch to stderr\r
+as NotmuchError(STATUS.XAPIAN_EXCEPTION, message=err).\r
+---\r
+ bindings/python/notmuch/database.py | 5 +++++\r
+ bindings/python/notmuch/globals.py | 24 ++++++++++++++++++++++++\r
+ 2 files changed, 29 insertions(+), 0 deletions(-)\r
+\r
+diff --git a/bindings/python/notmuch/database.py b/bindings/python/notmuch/database.py\r
+index 874087e..443980b 100644\r
+--- a/bindings/python/notmuch/database.py\r
++++ b/bindings/python/notmuch/database.py\r
+@@ -18,8 +18,10 @@ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'\r
+ """\r
+ \r
+ import os\r
++\r
+ from ctypes import c_int, c_char_p, c_void_p, c_uint, c_long, byref\r
+ from notmuch.globals import nmlib, STATUS, NotmuchError, Enum\r
++from notmuch.globals import RaiseStderrErrors\r
+ from notmuch.thread import Threads\r
+ from notmuch.message import Messages, Message\r
+ from notmuch.tag import Tags\r
+@@ -540,6 +542,9 @@ class Query(object):\r
+ if query_p is None:\r
+ NotmuchError(STATUS.NULL_POINTER)\r
+ self._query = query_p\r
++ # ensure Xapian errors from stderr get raised if query syntax is bad\r
++ with RaiseStderrErrors():\r
++ Query._count_messages(self._query)\r
+ \r
+ def set_sort(self, sort):\r
+ """Set the sort order future results will be delivered in\r
+diff --git a/bindings/python/notmuch/globals.py b/bindings/python/notmuch/globals.py\r
+index 77f2905..5e527ca 100644\r
+--- a/bindings/python/notmuch/globals.py\r
++++ b/bindings/python/notmuch/globals.py\r
+@@ -17,6 +17,10 @@ along with notmuch. If not, see <http://www.gnu.org/licenses/>.\r
+ Copyright 2010 Sebastian Spaeth <Sebastian@SSpaeth.de>'\r
+ """\r
+ \r
++import tempfile\r
++import sys\r
++import os\r
++\r
+ from ctypes import CDLL, c_char_p, c_int\r
+ from ctypes.util import find_library\r
+ \r
+@@ -98,3 +102,23 @@ class NotmuchError(Exception):\r
+ return self.args[0]\r
+ else:\r
+ return STATUS.status2str(self.args[1])\r
++\r
++\r
++class RaiseStderrErrors:\r
++ def __enter__(self):\r
++ sys.stderr.flush()\r
++ (self.errfd, fn) = tempfile.mkstemp()\r
++ self.ferr = os.fdopen(self.errfd, 'r')\r
++ os.unlink(fn)\r
++ self.oldstderr = os.dup(sys.stderr.fileno())\r
++ os.dup2(self.errfd, sys.stderr.fileno())\r
++\r
++ def __exit__(self, *args):\r
++ sys.stderr.flush()\r
++ os.dup2(self.oldstderr, sys.stderr.fileno())\r
++ os.close(self.oldstderr)\r
++ os.lseek(self.errfd, 0, 0)\r
++ err = self.ferr.read()\r
++ if err:\r
++ raise NotmuchError(STATUS.XAPIAN_EXCEPTION, message=err)\r
++ self.ferr.close()\r
+-- \r
+1.7.4.1\r
+\r