469,618 Members | 2,562 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,618 developers. It's quick & easy.

Reraise exception with modified stack

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
Jul 19 '05 #1
4 2550
Nicolas Fleury wrote:
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]

How about dropping reraise and changing:
reraise(...)
to:
addinfo(...)
raise

Where addinfo looks like:
def addinfo(exception, additionalInfo):
strFunc = getattr(exception, "__str__", None)
if not isinstance(strFunc, ExceptionStr):
strFunc = ExceptionStr(str(exception))
exception.__str__ = strFunc
strFunc.addinfo(additionalInfo)
So you finale would be:
if __name__ == '__main__':
def foo():
raise AttributeError('Test')
def bar():
foo()
try:
try:
try:
bar()
except Exception, exception:
addinfo(exception, "While doing x:")
raise
except Exception, exception:
addinfo(exception, "While doing y:")
raise
except Exception, exception:
addinfo(exception, "While doing z:")
raise

--Scott David Daniels
Sc***********@Acm.Org
Jul 19 '05 #2
Scott David Daniels wrote:
How about dropping reraise and changing:
reraise(...)
to:
addinfo(...)
raise


It doesn't work, or at least it doesn't do what I want. I want to keep
the same exception stack to be able to identify the original error. I
would like to avoid also writing in the caller something like
sys.exc_info()[-1].

Regards,
Nicolas
Jul 19 '05 #3
Nicolas Fleury wrote:
Scott David Daniels wrote:
How about dropping reraise and changing:
reraise(...)
to:
addinfo(...)
raise

It doesn't work, or at least it doesn't do what I want. I want to keep
the same exception stack to be able to identify the original error. I
would like to avoid also writing in the caller something like
sys.exc_info()[-1].

Regards,
Nicolas


Have you tried it? Looked to do what you described to me when I run a
sample. Note that is an unadorned raise with no args. The idea is to
simply modify the exception object and then use raise to carry the
whole original exception along as if not intercepted.

--Scott David Daniels
Sc***********@Acm.Org
Jul 19 '05 #4
Scott David Daniels wrote:
Have you tried it? Looked to do what you described to me when I run a
sample. Note that is an unadorned raise with no args. The idea is to
simply modify the exception object and then use raise to carry the
whole original exception along as if not intercepted.


Oups, sorry, I tried it but wrote "raise exception" instead of "raise".

Yes, that's a very good idea indeed. I'll change to that.

Thx,
Nicolas
Jul 19 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Barry Mossman | last post: by
5 posts views Thread by Simon Tamman {Uchiha Jax} | last post: by
5 posts views Thread by samuraign | last post: by
1 post views Thread by George2 | last post: by
9 posts views Thread by =?Utf-8?B?UmFq?= | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.