I'm writing a program that parses 10 websites, locates data files, saves the files, and then parses them to make data that can be readily used in the NumPy library. There are tons of errors this file encounters through bad links, poorly formed XML, missing entries, and other things I've yet to categorize. I initially made this program to handle errors like this:
try:
do_stuff()
except:
pass
But now I want to log errors:
try:
do_stuff()
except Exception, err:
print Exception, err
Note this is printing to a log file for later review. This usually prints very useless data. What I want is to print the exact same lines printed when the error triggers without the try-except intercepting the exception, but I don't want it to halt my program since it is nested in a series of for loops that I would like to see to completion.
traceback.format_exc()
orsys.exc_info()
will yield more info if that's what you want.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:...will display the traceback of the last exception:
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 usingprint_exception
:Producing:
Few pitfalls with this though:
From the doc of
sys_info
:but, from the same doc:
On the other hand, by allowing you to access the traceback associated with an exception, Python 3 produce a less surprising result:
... will display:
You will need to put the try/except inside the most innerloop where the error may occur, i.e.
... and so on
In other words, you will need to wrap statements that may fail in try/except as specific as possible, in the most inner-loop as possible.
If you're debugging and just want to see the current stack trace, you can simply call:
traceback.print_stack()
There's no need to manually raise an exception just to catch it again.
To get the precise stack trace, as a string, that would have been raised if no try/except were there to step over it, simply place this in the except block that catches the offending exception.
Here's how to use it (assuming
flaky_func
is defined, andlog
calls your favorite logging system):It's a good idea to catch and re-raise
KeyboardInterrupt
s, so that you can still kill the program using Ctrl-C. Logging is outside the scope of the question, but a good option is logging. Documentation for the sys and traceback modules.A remark about this answer's comments:
print(traceback.format_exc())
does a better job for me thantraceback.print_exc()
. With the latter, thehello
is sometimes strangely "mixed" with the traceback text, like if both want to write to stdout or stderr at the same time, producing weird output (at least when building from inside a text editor and viewing the output in the "Build results" panel).So I use: