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)
Answer from Ants Aasma on Stack Overflowimport 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)
Simplest form that worked for me.
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
How to get the error line?
Can I use logging to return line number where code failed?
Locating the line number where an exception occurs in python code - Stack Overflow
python - Getting line number from the exception object - Stack Overflow
I am currently using the following to capture exceptions. Is there a way of also returning the number of the line where the error occurred?
try:
except Exception as str_error:
logging.warning(str_error)
pass
what about this:
try:
if x:
print 'before statement 1'
statement1
print 'before statement 2' #ecc. ecc.
statement2
statement3
elif y:
statement4
statement5
statement6
else:
raise
except:
statement7
this is the straightforward workaround but I suggest to use a debugger
or even better, use the sys module :D
try:
if x:
print 'before statement 1'
statement1
print 'before statement 2' #ecc. ecc.
statement2
statement3
elif y:
statement4
statement5
statement6
else:
raise
except:
print sys.exc_traceback.tb_lineno
#this is the line number, but there are also other infos
I believe the several answers here recommending you manage your try/except blocks more tightly are the answer you're looking for. That's a style thing, not a library thing.
However, at times we find ourselves in a situation where it's not a style thing, and you really do need the line number to do some other programattic action. If that's what you're asking, you should consider the traceback module. You can extract all the information you need about the most recent exception. The tb_lineno function will return the line number causing the exception.
>>> import traceback
>>> dir(traceback)
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_format_final_exc_line', '_print', '_some_str', 'extract_stack', 'extract_tb', 'format_exc', 'format_exception', 'format_exception_only', 'format_list', 'format_stack', 'format_tb', 'linecache', 'print_exc', 'print_exception', 'print_last', 'print_list', 'print_stack', 'print_tb', 'sys', 'tb_lineno', 'types']
>>> help(traceback.tb_lineno)
Help on function tb_lineno in module traceback:
tb_lineno(tb)
Calculate correct line number of traceback given in tb.
Obsolete in 2.3
Newer versions of the traceback plumbing fix the issue prior to 2.3, allowing the code below to work as it was intended: (this is the "right way")
import traceback
import sys
try:
raise Exception("foo")
except:
for frame in traceback.extract_tb(sys.exc_info()[2]):
fname,lineno,fn,text = frame
print "Error in %s on line %d" % (fname, lineno)
The traceback object holds that info in the tb_lineno attribute:
import sys
# ...
except Exception as e:
trace_back = sys.exc_info()[2]
line = trace_back.tb_lineno
raise FlowException("Process Exception in line {}".format(line), e)
Tested on Python 3.6
class FlowException(Exception):
pass
def something():
raise ValueError
try:
something()
except Exception as e:
raise FlowException("Process Exception", e)
Output has line numbers:
Traceback (most recent call last):
File "/Users/diman/PycharmProjects/invites/test.py", line 8, in <module>
something()
File "/Users/diman/PycharmProjects/invites/test.py", line 5, in something
raise ValueError
ValueError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/diman/PycharmProjects/invites/test.py", line 10, in <module>
raise FlowException("Process Exception", e)
__main__.FlowException: ('Process Exception', ValueError())
For Python 2 try using internal logger ".exception()" method instead of using monstrous "sys" module.
import logging
logger = logging.getLogger()
try:
something()
except Exception as e:
logger.exception(e)
raise FlowException("Process Exception", e)
try this:
import logging
logger = logging.getLogger(__name__)
try:
specialization_object = Specialization.objects.get(name="My Test Specialization")
except Exception as ex:
logger.info(ex, exc_info=True) # exc_info will add traceback
further reading see here
If you can't for any reason use logging, There's the standard package traceback, and you can do something like:
traceback.print_exc(file=sys.stdout)