[Python-Dev] Adding content to exception messages

Nicolas Fleury nidoizo at yahoo.com
Sun May 29 13:00:24 CEST 2005


Nick Coghlan wrote:
> With PEP 344, this could simply be:
> 
>    try:
>        parser.parseFile(file)
>    exeption Exception, exception:
>        raise type(exception)("Error at line %s in file %s" % (x,y))
> 
> Introspectively,
> Nick.
> 

It doesn't work (unless I misundertand you).  For example, the 
exceptions.UnicodeTranslateError constructor needs 4 arguments, not 1. 
That's the reason why I think a parallel mechanism is necessary to add 
additional information when it is necessary to keep the same exception type.

I probably didn't explain myself well too.  Suppose this very hacky 
implementation working with the statu quo:

class ExceptionStr:
     def __init__(self, content):
         self.content = content
         self.infos = []
     def addinfo(self, info):
         self.infos.insert(0, info)
     def __call__(self):
         return '\n'.join(self.infos + [self.content])

import sys
def reraise(exception, info=None):
     strFunc = getattr(exception, "__str__", None)
     if not isinstance(strFunc, ExceptionStr):
         strFunc = ExceptionStr(str(exception))
         exception.__str__ = strFunc
     if info:
         strFunc.addinfo(info)
     raise exception, None, sys.exc_info()[-1]

The following code:

try:
     try:
         raise Exception("hello")
     except Exception, exception:
         reraise(exception, "doing x")
except Exception, exception:
     reraise(exception, "doing y")

would produce something like:

Traceback (most recent call last):
   File "somefile.py", line 7, in ?
     reraise(exception, "doing y")
   File "somefile.py", line 5, in ?
     reraise(exception, "doing x")
   File "somefile..py", line 3, in ?
     raise Exception("hello")
Exception: doing y
doing x
hello

(Note that having the lines 5 and 7 in the traceback is not wanted)

What I propose is to instead have something like:

try:
     try:
         raise Exception("hello")
     except Exception, exception:
         # have some way to reraise a copy of "exception"
         # or the same exception with additional info "doing x"
         # For example:
         exception.addinfo("doing x")
         raise exception from exception.__context__
except Exception, exception:
     # Idem with "doing y"

And have as output:

Traceback (most recent call last):
   File "somefile..py", line 3, in ?
     raise Exception("hello")
Additional info:
   doing y
   doing x
Exception: hello

Regards,
Nicolas



More information about the Python-Dev mailing list