Re-raising exceptions with modified message

samwyse samwyse at gmail.com
Sat Jul 7 23:13:45 CEST 2007


On Jul 5, 8:53 am, Christoph Zwerschke <c... at online.de> wrote:
> What is the best way to re-raise any exception with a message
> supplemented with additional information (e.g. line number in a
> template)? Let's say for simplicity I just want to add "sorry" to every
> exception message. My naive solution was this:
>
> try:
>      ...
> except Exception, e:
>      raise e.__class__, str(e) + ", sorry!"
>
> This works pretty well for most exceptions, e.g.
>
>  >>> try:
> ...     1/0
> ... except Exception, e:
> ...     raise e.__class__, str(e) + ", sorry!"
> ...
> Traceback (most recent call last):
>    File "<stdin>", line 4, in <module>
> ZeroDivisionError: integer division or modulo by zero, sorry!
>
> But it fails for some exceptions that cannot be instantiated with a
> single string argument, like UnicodeDecodeError which gets "converted"
> to a TypeError:
>
>  >>> try:
> ...     unicode('\xe4')
> ... except Exception, e:
> ...     raise e.__class__, str(e) + ", sorry!"
> ...
> Traceback (most recent call last):
>    File "<stdin>", line 4, in <module>
> TypeError: function takes exactly 5 arguments (1 given)
>
> Another approach is using a wrapper Extension class:
>
> class SorryEx(Exception):
>      def __init__(self, e):
>          self._e = e
>      def __getattr__(self, name):
>          return getattr(self._e, name)
>      def __str__(self):
>          return str(self._e) + ", sorry!"
>
> try:
>      unicode('\xe4')
> except Exception, e:
>      raise SorryEx(e)
>
> But then I get the name of the wrapper class in the message:
>
> __main__.SorryEx: 'ascii' codec can't decode byte 0xe4 in position 0:
> ordinal not in range(128), sorry!
>
> Yet another approach would be to replace the __str__ method of e, but
> this does not work for new style Exceptions (Python 2.5).
>
> Any suggestions?
>
> -- Chris

Can "try" statements be used in "except" clauses?  It appears so, thus
a hybrid approach might work well enough.

try:
    ...
except Exception, e:
    try:
        raise e.__class__, str(e) + ", sorry!"
    except TypeError:
        raise SorryEx(e)

That leaves the issue of the name being changed for
UnicodeDecodeError, which might be fixable by diddling with __name__
properties.  Or perhaps SorryEx needs to be a factory that returns
exception classes; the last line would be "SorryEx(e)()".  I'll have
to play with this a bit.




More information about the Python-list mailing list