Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When I catch an exception, how do I get the type, file, and line number of the previous frame?

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
like image 206
Claudiu Avatar asked Aug 18 '09 02:08

Claudiu


3 Answers

Add a line:

    tb = tb.tb_next

just after your call to sys.exc_info.

See the docs here under "Traceback objects".

like image 91
Alex Martelli Avatar answered Nov 09 '22 13:11

Alex Martelli


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()
like image 3
inerte Avatar answered Nov 09 '22 13:11

inerte


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.

like image 2
Ned Batchelder Avatar answered Nov 09 '22 14:11

Ned Batchelder