Given an Exception object (of unknown origin) is there way to obtain its traceback? I have code like this:
def stuff():
try:
.....
return useful
except Exception as e:
return e
result = stuff()
if isinstance(result, Exception):
result.traceback <-- How?
How can I extract the traceback from the Exception object once I have it?
The answer to this question depends on the version of Python you’re using.
In Python 3
It’s simple: exceptions come equipped with a
__traceback__attribute that contains the traceback. This attribute is also writable, and can be conveniently set using thewith_tracebackmethod of exceptions:These features are minimally described as part of the
raisedocumentation.All credit for this part of the answer should go to Vyctor, who first posted this information. I’m including it here only because this answer is stuck at the top, and Python 3 is becoming more common.
In Python 2
It’s annoyingly complex. The trouble with tracebacks is that they have references to stack frames, and stack frames have references to the tracebacks that have references to stack frames that have references to… you get the idea. This causes problems for the garbage collector. (Thanks to ecatmur for first pointing this out.)
The nice way of solving this would be to surgically break the cycle after leaving the
exceptclause, which is what Python 3 does. The Python 2 solution is much uglier: you are provided with an ad-hoc function,sys.exc_info(), which only works inside theexceptclause. It returns a tuple containing the exception, the exception type, and the traceback for whatever exception is currently being handled.So if you are inside the
exceptclause, you can use the output ofsys.exc_info()along with thetracebackmodule to do various useful things:But as your edit indicates, you’re trying to get the traceback that would have been printed if your exception had not been handled, after it has already been handled. That’s a much harder question. Unfortunately,
sys.exc_inforeturns(None, None, None)when no exception is being handled. Other relatedsysattributes don’t help either.sys.exc_tracebackis deprecated and undefined when no exception is being handled;sys.last_tracebackseems perfect, but it appears only to be defined during interactive sessions.If you can control how the exception is raised, you might be able to use
inspectand a custom exception to store some of the information. But I’m not entirely sure how that would work.To tell the truth, catching and returning an exception is kind of an unusual thing to do. This might be a sign that you need to refactor anyway.