How to print line number of error that is inside a function using except in Python?

Question:

I want to print an error’s line number and error message in a nicely displayed way. The follow is my code, which uses linecache:

import linecache

def func():
    if xx == 1:
        print('ok')

try:
    func()
except:
    exc_type, exc_obj, tb = sys.exc_info()
    f = tb.tb_frame
    lineno = tb.tb_lineno
    filename = f.f_code.co_filename
    linecache.checkcache(filename)
    line = linecache.getline(filename, lineno, f.f_globals)
    print_('ERROR - (LINE {} "{}"): {}'.format(lineno, line.strip(), exc_obj))

However, this only gives where the func() is called:

ERROR - (LINE 8 ""): name 'xx' is not defined

Is there a way to print the line number where the error actually occured, which should be Line 4? Or even better, can I print Line 8 and then trace back to line 4? For example, if I do not use try - except, the code:

def func():
    if xx == 1:
        print('ok')

func()

will give me the following error message, which is much better to locate the error:

  File "<input>", line 5, in <module>
  File "<input>", line 2, in func
NameError: name 'xx' is not defined. Did you mean: 'xxx'?
Asked By: SamTest

||

Answers:

You can use traceback and sys modules to get advanced traceback output like you are wishing for.

Here is an example:

import traceback
import sys

def func():
    zeroDivide = 1 / 0

try:
    func()

except Exception:
    print(traceback.format_exc()) # This line is for getting traceback.
    print(sys.exc_info()[2]) # This line is getting for the error type.

Output will be:

Traceback (most recent call last):
  File "b:abc1234ppppmain.py", line 10, in <module>
    func()
  File "b:abc1234ppppmain.py", line 7, in func     
    zeroDivide = 1 / 0

ZeroDivisionError: division by zero
Answered By: Refet

You can use the traceback module to get the line number of the error,

import traceback

def function():
    try:
        # code 
    except:
        tb_list = traceback.extract_tb(sys.exc_info()[2])
        line_number = tb_list[-1][1]
        print("An error occurred on line:", line_number)

You can use the traceback.extract_tb() function. This function returns a list of traceback objects, each of which contain information about the stack trace. The last element of this list, tb_list[-1], holds information about the line where the exception occurred. To access the line number, you can use the second element of this tuple, tb_list[-1][1]. This value can then be printed using the print() function.

Answered By: Bihi23

To get the line number as an int you can get the traceback as a list from traceback.extract_tb(). Looking at the last item gives you the line where the exception was raised:

#soPrintLineOfError2
import sys
import traceback

def func():
    if xx == 1:
        print('ok')

try:
    func()
except Exception as e:
    tb = sys.exc_info()[2]
    ss = traceback.extract_tb(tb)
    ss1 = ss[-1]
    print(ss1.line)
    print(ss1.lineno)

Output:

if xx == 1:
6
Answered By: quamrana
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.