Coder Perfect

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


Detecting an exception that would seem as follows:

Traceback (most recent call last):
  File "c:/", line 1, in <module>
    4 / 0
ZeroDivisionError: integer division or modulo by zero

I’d like to format it as follows:

ZeroDivisonError,, 1

Asked by Claudiu

Solution #1

import sys, os

    raise NotImplementedError("No error")
except Exception as e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
    print(exc_type, fname, exc_tb.tb_lineno)

Answered by Ants Aasma

Solution #2

I found the simplest form to be the most effective.

import traceback

except ZeroDivisionError:


Traceback (most recent call last):
  File "/path/to/", line 51, in <module>
ZeroDivisionError: division by zero

Process finished with exit code 0

Answered by nu everest

Solution #3

The source code for traceback.format exception() and called/related methods (Py v2.7.3) is quite helpful. I constantly forget to Read the Source, which is embarrassing. I simply did that because I was looking for comparable information and couldn’t find it. “How to recreate the same result as Python for an exception, with all the same details?” is a straightforward query. This will get you 90% of the way to whatever you’re looking for. I came up with this scenario because I was frustrated. I hope it is useful to others. (It certainly aided me! 😉

import sys, traceback

traceback_template = '''Traceback (most recent call last):
  File "%(filename)s", line %(lineno)s, in %(name)s
%(type)s: %(message)s\n''' # Skipping the "actual line" item

# Also note: we don't walk all the way through the frame stack in this example
# see
# (Imagine if the 1/0, below, were replaced by a call to test() which did 1/0.)

    exc_type, exc_value, exc_traceback = sys.exc_info() # most recent (if any) by default

    Reason this _can_ be bad: If an (unhandled) exception happens AFTER this,
    or if we do not delete the labels on (not much) older versions of Py, the
    reference we created can linger.

    traceback.format_exc/print_exc do this very thing, BUT note this creates a
    temp scope within the function.

    traceback_details = {
                         'filename': exc_traceback.tb_frame.f_code.co_filename,
                         'lineno'  : exc_traceback.tb_lineno,
                         'name'    : exc_traceback.tb_frame.f_code.co_name,
                         'type'    : exc_type.__name__,
                         'message' : exc_value.message, # or see traceback._some_str()

    del(exc_type, exc_value, exc_traceback) # So we don't leave our local labels/objects dangling
    # This still isn't "completely safe", though!
    # "Best (recommended) practice: replace all exc_type, exc_value, exc_traceback
    # with sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]

    print traceback.format_exc()
    print traceback_template % traceback_details

In response to this question specifically:

sys.exc_info()[0].__name__, os.path.basename(sys.exc_info()[2].tb_frame.f_code.co_filename), sys.exc_info()[2].tb_lineno

Answered by pythonlarry

Solution #4

Here’s an example of displaying the line number where the exception occurs.

import sys
except Exception as e:
    print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno), type(e).__name__, e)

print('And the rest of program continues')

Answered by Stryker

Solution #5

Without any imports, but also incompatible with modules that have been imported:

    raise TypeError("Hello, World!")  # line 2
except Exception as e:
        type(e).__name__,          # TypeError
        __file__,                  # /tmp/
        e.__traceback__.tb_lineno  # 2

python3 /tmp/ $ python3 /tmp/ /tmp/ 2 TypeError

To emphasize, this does not operate across imports or modules, so if you import X and then try: X.example(), the filename and line number will point to the line containing X.example() rather than the line where X.example() went wrong (). Please improve this answer if anyone knows how to retrieve the file name and line number from the last stack trace line (I expected something like e[-1].filename, but no such luck).

Answered by Luc

Post is based on