From this question, I'm now doing error handling one level down. That is, I call a function which calls another larger function, and I want where it failed in that larger function, not in the smaller function. Specific example. Code is:
import sys, os
def workerFunc():
return 4/0
def runTest():
try:
print workerFunc()
except:
ty,val,tb = sys.exc_info()
print "Error: %s,%s,%s" % (
ty.__name__,
os.path.split(tb.tb_frame.f_code.co_filename)[1],
tb.tb_lineno)
runTest()
Output is:
Error: ZeroDivisionError,tmp2.py,8
but line 8 is "print workerFunc()" - I know that line failed, but I want the line before:
Error: ZeroDivisionError,tmp2.py,4
Add a line:
tb = tb.tb_next
just after your call to sys.exc_info
.
See the docs here under "Traceback objects".
tb.tb_next
is your friend:
import sys, os
def workerFunc():
return 4/0
def runTest():
try:
print workerFunc()
except:
ty,val,tb = sys.exc_info()
print "Error: %s,%s,%s" % (
ty.__name__,
os.path.split(tb.tb_frame.f_code.co_filename)[1],
tb.tb_next.tb_lineno)
runTest()
But the traceback module does this and much more:
import traceback
def workerFunc():
return 4/0
def runTest():
try:
print workerFunc()
except:
print traceback.format_exc()
runTest()
You need to find the bottom of the traceback, so you need to loop along until there are no more frames. Do this to find the frame you want:
while tb.tb_next:
tb = tb.tb_next
after sys.exc_info. This will find the exception no matter how many call frames down it happened.
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