Many thanks for the excellent example!! You rock! Ben
On May 6, 2010, at 10:56 PM, Chris Rebert wrote: > On Thu, May 6, 2010 at 8:50 PM, Ben Cohen <[email protected]> wrote: >> Is there a pythonic way to collect and display multiple exceptions at the >> same time? >> >> For example let's say you're trying to validate the elements of a list and >> you'd like to validate as many of the elements as possible in one run and >> still report exception's raised while validating a failed element. >> >> eg -- I'd like to do something like this: >> >> errors = [] >> for item in data: >> try: >> process(item) >> except ValidationError as e: >> errors.append(e) >> raise MultipleValidationErrors(*errors) >> >> where if the raised MultipleValidationErrors exception goes uncaught the >> interpreter will print a nice traceback that includes the tracebacks of each >> raised ValidationError. But I don't know how MultipleValidationErrors >> should be written ... > > import sys, traceback > > def _traceback_for(exc_info): > return ''.join(traceback.format_exception(*exc_info)) > > # StandardError can obviously be replaced with > # whatever exception superclass you want. > class MultipleValidationErrors(StandardError): > def __init__(self, errors=None): > self.errors = errors or [] > > def __str__(self): > tracebacks = "\n\n".join(_traceback_for(exc_info) for exc_info in \ > self.errors) > parts=("See the following exception tracebacks:", "="*78, tracebacks) > msg = '\n'.join(parts) > return msg > > def capture_current_exception(self): > self.errors.append(sys.exc_info()) > > def do_raise(self): > """Raises itself if it contains any errors""" > if self.errors: > raise self > > > #Example usage: > multiple_err = MultipleValidationErrors() > for c in "hello": > try: > int(c) # obviously fails > except ValueError: # whatever error type you care about > multiple_err.capture_current_exception() > multiple_err.do_raise() > > > Output from example: > Traceback (most recent call last): > File "tmp.py", line 35, in <module> > multiple_err.do_raise() > File "tmp.py", line 25, in do_raise > raise self > __main__.MultipleValidationErrors: See the following exception tracebacks: > ============================================================================== > Traceback (most recent call last): > File "tmp.py", line 32, in <module> > int(c) # obviously fails > ValueError: invalid literal for int() with base 10: 'h' > > > Traceback (most recent call last): > File "tmp.py", line 32, in <module> > int(c) # obviously fails > ValueError: invalid literal for int() with base 10: 'e' > > > Traceback (most recent call last): > File "tmp.py", line 32, in <module> > int(c) # obviously fails > ValueError: invalid literal for int() with base 10: 'l' > > > Traceback (most recent call last): > File "tmp.py", line 32, in <module> > int(c) # obviously fails > ValueError: invalid literal for int() with base 10: 'l' > > > Traceback (most recent call last): > File "tmp.py", line 32, in <module> > int(c) # obviously fails > ValueError: invalid literal for int() with base 10: 'o' > > > Cheers, > Chris > -- > Go Tritons! > http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list
