A context manager and decorator that wrap common exception trapping and handling code so they may be applied with just a single line of code in the client.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | from __future__ import with_statement
from contextlib import contextmanager
from functools import wraps
import logging
@contextmanager
def error_trapping(ident=None):
''' A context manager that traps and logs exception in its block.
Usage:
with error_trapping('optional description'):
might_raise_exception()
this_will_always_be_called()
'''
try:
yield None
except Exception:
if ident:
logging.error('Error in ' + ident, exc_info=True)
else:
logging.error('Error', exc_info=True)
def trap_errors(f):
''' A decorator to trap and log exceptions '''
@wraps(f)
def wrapper(*args, **kwds):
with error_trapping(f.__name__):
return f(*args, **kwds)
return wrapper
|
I frequently write code that needs to continue in the face of unexpected exceptions. For example when processing a list of real-world data, if there is a problem with one datum I may want to log an exception and continue with the rest of the data.
The usual way to do that is with a try / except block with an error handler in the except block. This context manager wraps up the try / except / handler into a single line of client code. The decorator applies the context manager to an entire function.
This implementation uses the logging package to report the error but of course you can substitute whatever error handling code you prefer.