Reputation: 1287
I work on the useful introspection helpers on the exception, thus wanted to generalize the code rather than copy-pasting it all the time. I have
def state_on_exc(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
result = f(*args, **kwargs)
return result
except Exception as e:
ex_type, exc_value, tb = sys.exc_info()
if tb is not None:
prev = tb
curr = tb.tb_next
while curr is not None:
prev = curr
curr = curr.tb_next
print(prev.tb_frame.f_locals)
raise e
@state_on_exc
def apply(f):
return f
def myfunc():
a = 5
raise ValueError
apply(myfunc())
But the wrapper doesn't seem to be called on exception (it raised specifically in the myfunc()
) - it doesn't print any local variables. Is there any proper way to achieve the same, or any better way to do that?
Upvotes: 0
Views: 487
Reputation: 32542
Quite close.
Example:
from functools import wraps
def decorate(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except Exception as e:
# handle exception
print("handled exception:", type(e))
# re-raise
raise
return wrapper
def myfunc():
a = 5
raise ValueError
decorated_fun = decorate(myfunc)
decorated_fun()
The output is:
$ python3 test.py
handled exception: <class 'ValueError'>
Traceback (most recent call last):
File "tt.py", line 25, in <module>
decorated_fun()
File "tt.py", line 7, in wrapper
result = f(*args, **kwargs)
File "tt.py", line 22, in myfunc
raise ValueError
ValueError
Upvotes: 1