xapian exceptions not caught in python bindings?

Patrick Totzke patricktotzke at googlemail.com
Sat Jul 23 06:36:02 PDT 2011


Hi all,

I hope the patch I send is correctly formated, I'm still fumbling with
git send-email and the --in-reply-to option.
Anyhow, forgive my language, of course I didn't mean to be condescending in any
way by calling these prints garbage! It's just that it's highly unusual and very
'non-pythonic' that a module directly prints to stderr instead of raising exceptions
and if you work directly with a curseslike interface on a terminal these
errormessages litter my screen.

The patch I send is a suggestion how to fix the behaviour described in my last post.
It introduces a ContextManager class that can be used to raise messages from stderr
as Xapian exceptions like this:

> from notmuch.globals import RaiseStderrErrors
> with RaiseStderrErrors():
>  do_stuff()

Now, if one executes: 
------------
> from notmuch import Database
> bad_querystring = "test AND"
> query = Database().create_query(bad_querystring
---------------
one gets a nice Xapian exception
-----------------------
  File "syntax.py", line 4, in <module>
    query = Database().create_query(bad_querystring)
  File "/usr/local/lib/python2.7/dist-packages/notmuch/database.py", line 432, in create_query
    return Query(self, querystring)
  File "/usr/local/lib/python2.7/dist-packages/notmuch/database.py", line 514, in __init__
    self.create(db, querystr)
  File "/usr/local/lib/python2.7/dist-packages/notmuch/database.py", line 547, in create
    Query._count_messages(self._query)
  File "/usr/local/lib/python2.7/dist-packages/notmuch/globals.py", line 123, in __exit__
    raise NotmuchError(STATUS.XAPIAN_EXCEPTION, message=err)
notmuch.globals.NotmuchError: A Xapian exception occurred: Syntax: <expression> AND <expression>
Query string was: test AND
----------------------------

There are two problems with this suggestion however.
First, one needs to redirect sdterr to a tempfile: Using StringIO doesn't work since
just replacing sys.stderr with something else is not "low level" enough, the messages will
still get printed. An alternative is using os.dup2, which replaces the file descriptor
of stderr directly, but cStringIO objects dont have .fileno()..
see [0,1].
The second problem is, that creating a query object with a malformed querystring doesn't
print anything to stderr, only if you use that object errors get printed (notmuch/lib/query.cc).
Thus, I call count_messages() once after initialising a new notmuch.databas.Query object (at the end of  Query.create). This ensures that Query.__init__() raises an exception when given bad 
querystrings, but at the cost of triggering an unnecessary count_messages().

best,
/p



----
[0]: http://stackoverflow.com/questions/5903501/attributeerror-stringio-instance-has-no-attribute-fileno
[1]: http://code.activestate.com/recipes/577564-context-manager-for-low-level-redirection-of-stdou/


On Sun, Jul 17, 2011 at 04:51:41PM -0300, David Bremner wrote:
> On Sun, 17 Jul 2011 20:35:38 +0100, Patrick Totzke <patricktotzke at googlemail.com> wrote:
> > If you run the following snippet, you notice that not only do we get
> > xapian-garbage on stderr but we don't really get any exceptions at the
> > position where it would make sense:
> 
> I wouldn't call that "xapian-garbage" since it is output from
> libnotmuch.
> 
> d
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20110723/ff6685b7/attachment.pgp>


More information about the notmuch mailing list