Capturing Python run-time exceptions ...

Jelmer Vernooij jelmer at samba.org
Mon Mar 26 07:58:15 MDT 2012


On Mon, Mar 26, 2012 at 08:27:10AM +0200, Michael Ströder wrote:
> Richard Sharpe wrote:
> > 2012/3/25 Richard Sharpe <realrichardsharpe at gmail.com>:
> >> I need to get the following errors:
> >>
> >>       RuntimeError: (-1073741790, 'Access denied')
> >>
> >> It looks like I can do something like:
> >>
> >>    try:
> >>        some statements
> >>    except RuntimeError:
> >>        other statements
> >>
> >> It seems like there is a set there with two entries. How do I get
> >> access to those values.
> > 
> > OK, I found it in my Python book.
> > 
> >     except RuntimeError, val:
> > 
> > then val is the info that was printed by the default handler.
> Nitpicking: val is an instance of an exception object.
> 
> The exception class could have its own __str__() method leading to any output
> in the printed exception traceback. So what is printed in the traceback output
> is not necessarily the exact type of the data you could extract by accessing
> the object's attributes.
> 
> Furthermore for exception RuntimeError the Python 2.7 documentation says that
> there's only a string associated with it. But the example above (-1073741790,
> 'Access denied') looks like a tuple which is perfectly possible:
> 
> >>> raise RuntimeError((123,'foobar'))
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> RuntimeError: (123, 'foobar')
> >>>
> 
> So you cannot assume that it's always a 2-tuple when RuntimeError is raised.
> 
> Maybe the Samba code should define a custom exception class (if not already
> done) for which the caller can assume to find a tuple in the exception object.
> 
> If the caller is not interested in extracting the tuple items it could just
> call str(val) to always get a string somewhat representing the exception
> object (e.g. for logging).
You're right. The exceptions for most of the Samba modules aren't
ideal at the moment, and we should move to more specific exception
classes at some point.

The reason the situation is like this is a combination of laziness
(actually wanting to get something working) and consistency. I've
originally used RuntimeError for a couple of reasons:

 * We want a global type for these exceptions, not three dozen
   types with the same name defined in different modules
 * PyExc_RuntimeError is available everywhere in C bindings. It
   doesn't require half a dozen calls to import a type from another
   Python module. We don't (yet?) have a common library with utility
   functions that is used by all our Python modules.
 * It isn't entirely trivial to map NTSTATUS and WERROR
   codes to proper errors in Python. We probably want to raise
   MemoryError for NT_STATUS_NO_MEMORY for example, rather than simply
   raising an NTSTATUS exception with NT_STATUS_NO_MEMORY as status
   code. We should get this right once, rather than changing it on
   people later.
 * Originally we weren't catching these errors (we didn't have to),
   and were just letting them bubble up to the top of the stack
   so they were displayed when an error occurred.

We could have added NTSTATUSError and WError exception classes and
used them in some places, but that would be even more confusing -
users not knowing which of the two to expect.

Cheers,

Jelmer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20120326/62807630/attachment.pgp>


More information about the samba-technical mailing list