N
Nicolas Fleury
Hi,
I've made a small utility to re-raise an exception with the same stack
as before with additional information in it. Since I want to keep the
same exception type and that some types have very specific constructors
(which take, for example, more than one parameter), the only safe way I
have found to made it is by hacking the str representation:
import sys
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' + '\n'.join(self.infos + [self.content])
def reraise(exception, additionalInfo):
strFunc = getattr(exception, "__str__", None)
if not isinstance(strFunc, ExceptionStr):
strFunc = ExceptionStr(str(exception))
exception.__str__ = strFunc
strFunc.addinfo(additionalInfo)
raise exception, None, sys.exc_info()[-1]
if __name__ == '__main__':
def foo():
raise AttributeError('Test')
def bar():
foo()
try:
try:
try:
bar()
except Exception, exception:
reraise(exception, "While doing x:")
except Exception, exception:
reraise(exception, "While doing y:")
except Exception, exception:
reraise(exception, "While doing z:")
Suppose the resulted traceback is:
Traceback (most recent call last):
File "somefile.py", line 52, in ?
reraise(exception, "While doing z:", MyException)
File "somefile.py", line 50, in ?
reraise(exception, "While doing y:", Exception)
File "somefile.py", line 48, in ?
reraise(exception, "While doing x:")
File "somefile.py", line 46, in ?
bar()
File "somefile.py", line 40, in bar
foo()
File "somefile.py", line 38, in foo
raise AttributeError('Test')
AttributeError:
While doing z:
While doing y:
While doing x:
Test
I would like to know how to code the reraise function so that the lines
48, 50 and 52 don't appear in the stack. Is it possible?
Thx and regards,
Nicolas
I've made a small utility to re-raise an exception with the same stack
as before with additional information in it. Since I want to keep the
same exception type and that some types have very specific constructors
(which take, for example, more than one parameter), the only safe way I
have found to made it is by hacking the str representation:
import sys
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' + '\n'.join(self.infos + [self.content])
def reraise(exception, additionalInfo):
strFunc = getattr(exception, "__str__", None)
if not isinstance(strFunc, ExceptionStr):
strFunc = ExceptionStr(str(exception))
exception.__str__ = strFunc
strFunc.addinfo(additionalInfo)
raise exception, None, sys.exc_info()[-1]
if __name__ == '__main__':
def foo():
raise AttributeError('Test')
def bar():
foo()
try:
try:
try:
bar()
except Exception, exception:
reraise(exception, "While doing x:")
except Exception, exception:
reraise(exception, "While doing y:")
except Exception, exception:
reraise(exception, "While doing z:")
Suppose the resulted traceback is:
Traceback (most recent call last):
File "somefile.py", line 52, in ?
reraise(exception, "While doing z:", MyException)
File "somefile.py", line 50, in ?
reraise(exception, "While doing y:", Exception)
File "somefile.py", line 48, in ?
reraise(exception, "While doing x:")
File "somefile.py", line 46, in ?
bar()
File "somefile.py", line 40, in bar
foo()
File "somefile.py", line 38, in foo
raise AttributeError('Test')
AttributeError:
While doing z:
While doing y:
While doing x:
Test
I would like to know how to code the reraise function so that the lines
48, 50 and 52 don't appear in the stack. Is it possible?
Thx and regards,
Nicolas