How to Catch and Print the Full Exception Traceback Without Halting/Exiting the Program

How to catch and print the full exception traceback without halting/exiting the program?

Some other answer have already pointed out the traceback module.

Please notice that with print_exc, in some corner cases, you will not obtain what you would expect. In Python 2.x:

import traceback

try:
raise TypeError("Oups!")
except Exception, err:
try:
raise TypeError("Again !?!")
except:
pass

traceback.print_exc()

...will display the traceback of the last exception:

Traceback (most recent call last):
File "e.py", line 7, in <module>
raise TypeError("Again !?!")
TypeError: Again !?!

If you really need to access the original traceback one solution is to cache the exception infos as returned from exc_info in a local variable and display it using print_exception:

import traceback
import sys

try:
raise TypeError("Oups!")
except Exception, err:
try:
exc_info = sys.exc_info()

# do you usefull stuff here
# (potentially raising an exception)
try:
raise TypeError("Again !?!")
except:
pass
# end of useful stuff

finally:
# Display the *original* exception
traceback.print_exception(*exc_info)
del exc_info

Producing:

Traceback (most recent call last):
File "t.py", line 6, in <module>
raise TypeError("Oups!")
TypeError: Oups!

Few pitfalls with this though:

  • From the doc of sys_info:

    Assigning the traceback return value to a local variable in a function that is handling an exception will cause a circular reference. This will prevent anything referenced by a local variable in the same function or by the traceback from being garbage collected. [...] If you do need the traceback, make sure to delete it after use (best done with a try ... finally statement)

  • but, from the same doc:

    Beginning with Python 2.2, such cycles are automatically reclaimed when garbage collection is enabled and they become unreachable, but it remains more efficient to avoid creating cycles.


On the other hand, by allowing you to access the traceback associated with an exception, Python 3 produce a less surprising result:

import traceback

try:
raise TypeError("Oups!")
except Exception as err:
try:
raise TypeError("Again !?!")
except:
pass

traceback.print_tb(err.__traceback__)

... will display:

  File "e3.py", line 4, in <module>
raise TypeError("Oups!")

Get exception description and stack trace which caused an exception, all as a string

See the traceback module, specifically the format_exc() function. Here.

import traceback

try:
raise ValueError
except ValueError:
tb = traceback.format_exc()
else:
tb = "No error"
finally:
print tb

How to print the stack trace of an exception object in Python?

It's a bit inconvenient, but you can use traceback.print_exception. Given an exception ex:

traceback.print_exception(type(ex), ex, ex.__traceback__)

Example:

import traceback

try:
1/0
except Exception as ex:
traceback.print_exception(type(ex), ex, ex.__traceback__)

# output:
# Traceback (most recent call last):
# File "untitled.py", line 4, in <module>
# 1/0
# ZeroDivisionError: division by zero

Print an error message without printing a traceback and close the program when a condition is not met

You can use a try: and then except Exception as inst:
What that will do is give you your error message in a variable named inst and you can print out the arguments on the error with inst.args. Try printing it out and seeing what happens, and is any item in inst.args is the one you are looking for.

EDIT Here is an example I tried with pythons IDLE:

>>> try:
open("epik.sjj")
except Exception as inst:
d = inst

>>> d
FileNotFoundError(2, 'No such file or directory')
>>> d.args
(2, 'No such file or directory')
>>> d.args[1]
'No such file or directory'
>>>

EDIT 2: as for closing the program you can always raise and error or you can use sys.exit()

Why do I have to import traceback if it already exists?

The default behavior of Python when an exception is raised that isn't caught in a try...except is to print a traceback and exit. If you do catch it, then the default doesn't happen. You have to decide what to do with it. If you decide to print the traceback you now have to explicitly do it by importing the traceback module and using the methods there. However, that's not strictly necessary as you could just inspect the current traceback object (from sys.exc_info()), and write your own formatter.

How to get a complete exception stack trace in Python

I don't know if there is a better way, but here's what I did:

import traceback
import sys

def format_exception(e):
exception_list = traceback.format_stack()
exception_list = exception_list[:-2]
exception_list.extend(traceback.format_tb(sys.exc_info()[2]))
exception_list.extend(traceback.format_exception_only(sys.exc_info()[0], sys.exc_info()[1]))

exception_str = "Traceback (most recent call last):\n"
exception_str += "".join(exception_list)
# Removing the last \n
exception_str = exception_str[:-1]

return exception_str

def main1():
main2()

def main2():
try:
main3()
except Exception as e:
print "Printing only the traceback above the current stack frame"
print "".join(traceback.format_exception(sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]))
print
print "Printing the full traceback as if we had not caught it here..."
print format_exception(e)

def main3():
raise Exception()

if __name__ == '__main__':
main1()

And here's the output I get:

Printing only the traceback above the current stack frame
Traceback (most recent call last):
File "exc.py", line 22, in main2
main3()
File "exc.py", line 31, in main3
raise Exception()
Exception

Printing the full traceback as if we had not caught it here...
Traceback (most recent call last):
File "exc.py", line 34, in <module>
main1()
File "exc.py", line 18, in main1
main2()
File "exc.py", line 22, in main2
main3()
File "exc.py", line 31, in main3
raise Exception()
Exception

System not exiting in exception

This should fix the problem.

import sys
import os

def get_words():

print("File:",FILENAME)

if os.path.exists(FILENAME):
with open(FILENAME, 'r') as f:
words2 = f.read()

return words2.split(" ")
else:
print("File {} not found.".format(FILENAME))
sys.exit()

words = get_words()

How do I print an exception in Python?

For Python 2.6 and later and Python 3.x:

except Exception as e: print(e)

For Python 2.5 and earlier, use:

except Exception,e: print str(e)


Related Topics



Leave a reply



Submit