How To Get A Complete Exception Stack Trace In Python
Solution 1:
Here's a function based on this answer. It will also work when no exception is present:
deffull_stack():
import traceback, sys
exc = sys.exc_info()[0]
stack = traceback.extract_stack()[:-1] # last one would be full_stack()if exc isnotNone: # i.e. an exception is presentdel stack[-1] # remove call of full_stack, the printed exception# will contain the caught exception caller instead
trc = 'Traceback (most recent call last):\n'
stackstr = trc + ''.join(traceback.format_list(stack))
if exc isnotNone:
stackstr += ' ' + traceback.format_exc().lstrip(trc)
return stackstr
print full_stack()
will print the full stack trace up to the top, including e.g. IPython's interactiveshell.py
calls, since there is (to my knowledge) no way of knowing who would catch exceptions. It's probably not worth figuring out anyway...
If print full_stack()
is called from within an except
block, full_stack
will include the stack trace down to the raise
. In the standard Python interpreter, this will be identical to the message you receive when not catching the exception (Which is why that del stack[-1]
is there, you don't care about the except
block but about the try
block).
Solution 2:
I don't know if there is a better way, but here's what I did:
import traceback
import sys
def format_exception(e):
exception_list = traceback.format_stack()
exception_list = exception_list[:-2]
exception_list.extend(traceback.format_tb(sys.exc_info()[2]))
exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1]))
exception_str = "Traceback (most recent call last):\n"
exception_str += "".join(exception_list)
# Removing the last \n
exception_str = exception_str[:-1]
return exception_str
def main1():
main2()
def main2():
try:
main3()
except Exception as e:
print "Printing only the traceback above the current stack frame"
print "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))
print
print "Printing the full traceback as if we had not caught it here..."
print format_exception(e)
def main3():
raise Exception()
if __name__ == '__main__':
main1()
And here's the output I get:
Printing only the traceback above the current stack frame
Traceback (most recent calllast):
File "exc.py", line 22, in main2
main3()
File "exc.py", line 31, in main3
raise Exception()
Exception
Printing the full traceback as if we had not caught it here...
Traceback (most recent calllast):
File "exc.py", line 34, in<module>
main1()
File "exc.py", line 18, in main1
main2()
File "exc.py", line 22, in main2
main3()
File "exc.py", line 31, in main3
raise Exception()
Exception
Solution 3:
Use
traceback.print_stack()
http://docs.python.org/library/traceback.html#traceback.print_stack
suxmac2 $ python out.py
File "out.py", line 16, in <module>
a()
File "out.py", line 5, in a
b()
File "out.py", line 11, in b
traceback.print_stack()
Solution 4:
Here is a bit better variant of Tobias Kienzler answer. It works same, but can be called not right in except
block, but somewhere deeper.
In other words, this variant will print same stacks, when called like
try:
...
except Exception:
print full_stack()
or
def print_full_stack():
print full_stack()
try:
...
except Exception:
print_full_stack()
Here is code:
deffull_stack():
import traceback, sys
exc = sys.exc_info()[0]
if exc isnotNone:
f = sys.exc_info()[-1].tb_frame.f_back
stack = traceback.extract_stack(f)
else:
stack = traceback.extract_stack()[:-1] # last one would be full_stack()
trc = 'Traceback (most recent call last):\n'
stackstr = trc + ''.join(traceback.format_list(stack))
if exc isnotNone:
stackstr += ' ' + traceback.format_exc().lstrip(trc)
return stackstr
Post a Comment for "How To Get A Complete Exception Stack Trace In Python"