Like any modern language, Python comes along with a nice traceback module. This module gives you stack traces from the line of code where an exception is raised up to the next try-except clause. So, you can easily catch exceptions and write stack traces into a debug log. This debugging technique is pretty handy to drill down bugs and I use it a lot in prototyping.
Using the traceback module is straight forward for evident programming mistakes. However, real bugs are context-sensitive and they can hardly be reproduced without the actual data that was processed when an exception was raised. If you can reproduce a specific bug, you can add some logging code in front and inspect the variables the next time the bug is triggered. But if a bug occurs once in a blue moon, you’d be better in logging the data the first time an exception raises.
import traceback
def erroneous_function():
ham = u"unicode string with umlauts äöü."
eggs = "binary string with umlauts äöü."
i = 23
if i>5:
raise Exception("it's true!")
try:
erroneous_function()
except:
print traceback.format_exc(with_vars=True)
Here’s my solution; an improved Python traceback module the logs variables from the local scope next to the affected code. You can find a working copy in our Mercirual repository (see the below).
Traceback (most recent call last):
File "test.py", line 16, in <module>
Local variables:
erroneous_function = <function erroneous_function at 0x7ff6d82b...
__builtins__ = <module '__builtin__' (built-in)>
__file__ = "test.py"
traceback = <module 'traceback' from '/srv/www/vhosts/dev.teamr...
__name__ = "__main__"
__doc__ = None
erroneous_function()
File "test.py", line 13, in erroneous_function
Local variables:
i = 23
eggs = "binary string with umlauts \xc3\xa4\xc3\xb6\xc3\xbc."
ham = u"unicode string with umlauts ???."
raise Exception("it's true!")
Exception: it's true!
I am not sure if it is the “right” solution as sensitive information might be logged. This might have security implications for some real-world scenarios where webapps report stack traces to the end user (e.g. by using cgitb in production).
Credit: this code was inspired by format_exc_plus by Bryn Keller.
2010-01-28: there’s an active discussion on python-dev.
