Take the 2-minute tour ×

Catching an exception that would print like this:

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

I want to format it into:

ZeroDivisonError, tmp.py, 1
share|improve this question
Use the built-in traceback module. –  Ned Deily Aug 14 '09 at 16:10
It may also be helpful to print line of code, where exception happened: see stackoverflow.com/questions/14519177/… –  Apogentus Nov 28 '13 at 10:52
add comment

3 Answers

up vote 65 down vote accepted
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)
share|improve this answer
You should be careful about unpacking sys.exc_info() into local variables, since if you get an exception in the except handler, the local vars could get kept in a circular reference and not GC'd. Best practice is to always just use slices off of sys.exc_info() instead. Or use other modules like traceback, as other posters have suggested. –  Daniel Pryden Aug 17 '09 at 23:13
is tb just exc_tb? and os.path.split(blabla)[1] is os.path.basename(balbal) –  sunqiang Aug 20 '09 at 1:23
Is this thread-safe? –  RobM Mar 25 '11 at 15:58
With this code, I get (when try: 1/0) : <type 'exceptions.ZeroDivisionError'> integer division or modulo by zero. How to have ZeroDivisionError: integer division or modulo by zero instead ? –  Basj Feb 22 at 9:19
@Basj: With sys.exc_info()[0].__name__ you get the plain name of the type. –  Johannes Overmann Mar 3 at 17:21
add comment
except Exception as e:
    import traceback, os.path
    top = traceback.extract_stack()[-1]
    print ', '.join([type(e).__name__, os.path.basename(top[0]), str(top[1])])
share|improve this answer
str(top[1]) as Error-line-number doesn't work for me but Ants Aasma's answer does. –  el_Salmon Jul 31 '12 at 15:37
I think you wanted traceback.extract_tb(), not extract_stack() –  raylu Oct 5 '12 at 7:34
@raylu extract_stack gets the current stack trace; extract_tb needs a traceback object as a parameter. So extract_stack is correct. –  balpha Oct 5 '12 at 7:37
Only if the actual exception is thrown in the try. If it's in a method, extract_stack() just gives you the line of the call: codepad.org/ivJe0q9B –  raylu Oct 5 '12 at 9:10
The above code does not work at all for me on python 2.7 –  Jonesome Dec 4 '13 at 21:52
show 1 more comment

Source (Py v2.7.3) for traceback.format_exception() and called/related functions helps greatly. Embarrassingly, I always forget to Read the Source. I only did so for this after searching for similar details in vain. A simple question, "How to recreate the same output as Python for an exception, with all the same details?" This would get anybody 90+% to whatever they're looking for. Frustrated, I came up with this example. I hope it helps others. (It sure helped 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 hg.python.org/cpython/file/8dffb76faacc/Lib/traceback.py#l280
# (Imagine if the 1/0, below, were replaced by a call to test() which did 1/0.)

    # http://docs.python.org/2/library/sys.html#sys.exc_info
    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 specific answer to this query:

sys.exc_info()[0].__name__, os.path.basename(sys.exc_info()[2].tb_frame.f_code.co_filename), sys.exc_info()[2].tb_lineno
share|improve this answer
@thatjuan: 43 lines, not 50. And that's including my gratuitous spacing and copious notes... unless you really were happy it was "only 50", in which case it can be made to be "much shorter"...? :> –  Python Larry Jun 21 '13 at 14:43
add comment

Your Answer


