The traceback module is great for capturing and handling exceptions, but in the following example it seems to capture an incomplete stack from the most recent exception.
Consider two files, one say "mymod.py":
import sys, traceback
def func():
try:
otherfunc()
except:
raise
#traceback.print_exc()
def otherfunc():
raise Exception( 'fake' )
And another one say "myfile.py":
from mymod import *
func()
Running myfile.py gives:
Traceback (most recent call last):
File "myfile.py", line 2, in <module>
func()
File "/Users/rrdrake/temp/mymod.py", line 5, in func
otherfunc()
File "/Users/rrdrake/temp/mymod.py", line 11, in otherfunc
raise Exception( 'fake' )
Now change mymod.py to comment out the "raise" and uncomment the print_exc line. Then we get
Traceback (most recent call last):
File "/Users/rrdrake/temp/mymod.py", line 5, in func
otherfunc()
File "/Users/rrdrake/temp/mymod.py", line 11, in otherfunc
raise Exception( 'fake' )
Exception: fake
Notice that print_exc() does not include the myfile.py frame while re-raising does. How can I make print_exc() include the origin calling frame?
Note that if I add a traceback.print_stack() in the except block, it does include the myfile.py frame, so the information seems to be available.
In your first case, the exception from your raise
call bubbles up at the top level of the script. Python calls sys.excepthook()
, which displays the full traceback.
In your second case, the exception is caught and print_exc()
is used to print the exception, and this stops at the calling function (otherfunc()
in your case) so you don't get the full traceback.
You can change that by using your own traceback/exception print function, something along those lines:
def print_full_stack(tb=None):
if tb is None:
tb = sys.exc_info()[2]
print 'Traceback (most recent call last):'
for item in reversed(inspect.getouterframes(tb.tb_frame)[1:]):
print ' File "{1}", line {2}, in {3}\n'.format(*item),
for line in item[4]:
print ' ' + line.lstrip(),
for item in inspect.getinnerframes(tb):
print ' File "{1}", line {2}, in {3}\n'.format(*item),
for line in item[4]:
print ' ' + line.lstrip(),
Just replace traceback.print_exc()
with print_full_stack()
. This function involves the inspect
module to get code frames.
You can read this blog for much more information: http://blog.dscpl.com.au/2015/03/generating-full-stack-traces-for.html
Beware, the code in the above article has some indentation errors...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With