Problem
Detecting an exception that would seem as follows:
Traceback (most recent call last):
File "c:/tmp.py", line 1, in <module>
4 / 0
ZeroDivisionError: integer division or modulo by zero
I’d like to format it as follows:
ZeroDivisonError, tmp.py, 1
Asked by Claudiu
Solution #1
import sys, os
try:
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
try:
print(4/0)
except ZeroDivisionError:
print(traceback.format_exc())
Output
Traceback (most recent call last):
File "/path/to/file.py", line 51, in <module>
print(4/0)
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 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.)
try:
1/0
except:
# 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
print traceback.format_exc()
print
print traceback_template % traceback_details
print
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
try:
print(5/0)
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:
try:
raise TypeError("Hello, World!") # line 2
except Exception as e:
print(
type(e).__name__, # TypeError
__file__, # /tmp/example.py
e.__traceback__.tb_lineno # 2
)
python3 /tmp/example.py $ python3 /tmp/example.py /tmp/example.py 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 https://stackoverflow.com/questions/1278705/when-i-catch-an-exception-how-do-i-get-the-type-file-and-line-number