At times you will want to catch an exception and extract the stack trace from the exception object to capture it somewhere (for instance log it).
In our codebase, we generally aim to handle all kinds of unexpected or incorrect input and output by putting validations and expecting certain kinds of exceptions (try/except). But there still remain cases where we want a “catch-all” behaviour of simply expecting any kind of
Exception and capturing/logging the stack trace for future debugging.
So if you want to extract and capture the entire stack trace from an exception object in Python, then the right way is to use the
traceback Python library that provides a standard interface to extract, format and print stack traces of Python programs (including those associated with an exception object –
In most cases, the
traceback.format_exc() method should do the job. It returns a string containing:
- A header that says
Traceback (most recent call last):
- Stack traceback
- The exception type and value after the stack trace (eg:
NameError: name 'some_var' is not defined)
The format is similar to the exception strings/output that the Python interpreter throws to
stdout when it encounters an error in your program. Let’s see a simple example of how to get the traceback:
# tb.py import traceback def func1(): raise ValueError("Some error occurred!") def func2(): return func1() def func3(): try: func2() except Exception as e: # Return the traceback/stack trace as a string return traceback.format_exc() print(func3())
When you run the code above, you’ll see the returned traceback printed in your terminal:
$ python tb.py Traceback (most recent call last): File "tb.py", line 12, in func3 func2() File "tb.py", line 8, in func2 return func1() File "tb.py", line 5, in func1 raise ValueError("Some error occurred!") ValueError: Some error occurred!
Feel free to go through the other methods in the docs. For instance, you can use
traceback.print_exc() to write to a file instead of returning a string:
... def func3(): try: func2() except Exception as e: with open('print.txt', 'w+') as f: traceback.print_exc(file=f) print(func3())
Or if you want to generate the traceback string by explicitly passing the exception object (for some reason), then something like this will help:
... def func3(): try: func2() except Exception as e: return ''.join(traceback.TracebackException.from_exception(e).format()) print(func3())
Also with a combination of
traceback.extract_stack(), one can extract the raw traceback of the “current stack frame” which can help capture even more information like who was the caller of
current_stack_frame = traceback.format_list(traceback.extract_stack()) print(''.join(current_stack_frame))
Bonus: Instead of accessing the traceback, if you just want to log it in your
except block, then read this article.