Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Musings: Using decorators to reduce duplicate exception handling

Reply
Thread Tools

Re: Musings: Using decorators to reduce duplicate exception handling

 
 
Cameron Simpson
Guest
Posts: n/a
 
      02-18-2009
On 17Feb2009 15:12, J Kenneth King <(E-Mail Removed)> wrote:
| I recently started a project called TracShell
| (http://code.google.com/p/tracshell) where I make heavy use of the
| xmlrpclib core module.
|
| When the number of RPC calls was small, wrapping each call in try/except
| was acceptable. [...]
| To combat the duplication, my clever idea was to use a function
| decorator to wrap any function that used xmlrpclib calls:
| def catch_errors(fn):
[...]
| Maybe I could rename the decorator to something meaningful, but besides
| that it works pretty well. Now any function I write in my class that
| uses RPC calls can be wrapped by this decorator and have the exception
| handling done in a uniform way for these particular exceptions.

My Python fu is still weak, but I had a similar issue last year and
wrote a context manager, used thus:

with NoExceptions(handler):
... do stuff that may break ...

The constructor takes a handleException argument (which may be None, but it
has to be explicit) to tune which exceptions are caught; default is
everything. This was for a daemon thread that did RPC calls, so it was
actually fairly important to never die; normally you'd want to catch only
specific exceptions.

Code:

class NoExceptions(object):
''' A context manager to catch _all_ exceptions and log them.
Arguably this should be a bare try...except but that's syntacticly
noisy and separates the catch from the top.
'''

def __init__(self, handleException):
''' Initialise the NoExceptions context manager.
The handleException is a callable which
expects (exc_type, exc_value, traceback)
and returns True or False for the __exit__
method of the manager.
If handleException is None, the __exit__ method
always returns True, suppressing any exception.
'''
self.__handler = handleException

def __enter__(self):
pass

def __exit__(self, exc_type, exc_value, traceback):
if self.__handler is not None:
return self.__handler(exc_type, exc_value, traceback)
if exc_type is not None:
print >>sys.stderr, "ignore %s" % (exc_type,)
return True

It doesn't actually solve your duplication issue and is a bit of a niche
application, but it's a lot shorter than an inline try/except and to my eye
reads a little better, and it keeps the exception handling up front at the
calling end where it is visible.

Cheers,
--
Cameron Simpson <(E-Mail Removed)> DoD#743
http://www.cskk.ezoshosting.com/cs/
 
Reply With Quote
 
 
 
 
J Kenneth King
Guest
Posts: n/a
 
      02-19-2009
Cameron Simpson <(E-Mail Removed)> writes:

> On 17Feb2009 15:12, J Kenneth King <(E-Mail Removed)> wrote:
> | I recently started a project called TracShell
> | (http://code.google.com/p/tracshell) where I make heavy use of the
> | xmlrpclib core module.
> |
> | When the number of RPC calls was small, wrapping each call in try/except
> | was acceptable. [...]
> | To combat the duplication, my clever idea was to use a function
> | decorator to wrap any function that used xmlrpclib calls:
> | def catch_errors(fn):
> [...]
> | Maybe I could rename the decorator to something meaningful, but besides
> | that it works pretty well. Now any function I write in my class that
> | uses RPC calls can be wrapped by this decorator and have the exception
> | handling done in a uniform way for these particular exceptions.
>
> My Python fu is still weak, but I had a similar issue last year and
> wrote a context manager, used thus:
>
> with NoExceptions(handler):
> ... do stuff that may break ...
>
> The constructor takes a handleException argument (which may be None, but it
> has to be explicit) to tune which exceptions are caught; default is
> everything. This was for a daemon thread that did RPC calls, so it was
> actually fairly important to never die; normally you'd want to catch only
> specific exceptions.
>
> Code:
>
> class NoExceptions(object):
> ''' A context manager to catch _all_ exceptions and log them.
> Arguably this should be a bare try...except but that's syntacticly
> noisy and separates the catch from the top.
> '''
>
> def __init__(self, handleException):
> ''' Initialise the NoExceptions context manager.
> The handleException is a callable which
> expects (exc_type, exc_value, traceback)
> and returns True or False for the __exit__
> method of the manager.
> If handleException is None, the __exit__ method
> always returns True, suppressing any exception.
> '''
> self.__handler = handleException
>
> def __enter__(self):
> pass
>
> def __exit__(self, exc_type, exc_value, traceback):
> if self.__handler is not None:
> return self.__handler(exc_type, exc_value, traceback)
> if exc_type is not None:
> print >>sys.stderr, "ignore %s" % (exc_type,)
> return True
>
> It doesn't actually solve your duplication issue and is a bit of a niche
> application, but it's a lot shorter than an inline try/except and to my eye
> reads a little better, and it keeps the exception handling up front at the
> calling end where it is visible.
>
> Cheers,


Ah, that's pretty interesting. I've found a couple other decorator-style
recipes in the cookbooks online (http://code.activestate.com/recipes/408937/).

I think you see my point: every single RPC call needs to be caught just
in case because they are so volatile -- yet you're always looking for
the exact same exception everywhere... too noisy to have inline
try/except. I wonder if there are other use cases where Python
developers have found the need to abstract away repetitive exception
handling.

I think this is the first I've seen the newer Python context managers
being used (though it sneakily looks a lot like what Lisp calls,
"unwind-protect"). Neat idea.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Musings: Using decorators to reduce duplicate exception handling J Kenneth King Python 3 02-22-2009 04:52 PM
Block-structured resource handling via decorators John Perks and Sarah Mount Python 5 07-30-2005 11:21 AM
Is't possible to reduce the text duplicate Martin Andersson XML 0 02-02-2005 10:09 PM
better to compress the jpeg or reduce resolution or reduce pixel size? Mr.Will Digital Photography 8 10-08-2004 03:16 PM
PEP 318 decorators are not Decorators Arien Malec Python 11 08-16-2004 06:38 PM



Advertisments