How to parse a traceback to get the last frame in Python
Extracts the innermost frame's file, line, and function name from a Python traceback object.
Python code
32 linesimport sys
import traceback
def parse_traceback_last_frame(exc_info):
"""Return the file, line, and function of the last (innermost) frame."""
_, _, tb = exc_info
last_tb = tb
while last_tb.tb_next is not None:
last_tb = last_tb.tb_next
filename = last_tb.tb_frame.f_code.co_filename
lineno = last_tb.tb_lineno
function = last_tb.tb_frame.f_code.co_name
return {"file": filename, "line": lineno, "function": function}
def inner():
return 1 / 0
def outer():
return inner()
if __name__ == "__main__":
try:
outer()
except ZeroDivisionError:
exc_info = sys.exc_info()
info = parse_traceback_last_frame(exc_info)
print(f"Last frame: {info['function']}() in {info['file']}:{info['line']}")
print(traceback.format_exc().strip())
Output
Last frame: inner() in /path/to/script.py:16
Traceback (most recent call last):
File "/path/to/script.py", line 34, in <module>
outer()
File "/path/to/script.py", line 31, in outer
return inner()
File "/path/to/script.py", line 26, in inner
return 1 / 0
ZeroDivisionError: division by zero
How it works
The traceback object from sys.exc_info() contains linked frames from the outermost to the innermost. Walking tb_next until None reaches the innermost frame, which holds the exact location of the error. Accessing tb_frame.f_code gives code metadata like the function name, and tb_lineno gives the failing line number. This approach is useful for custom error reporting or logging that highlights the root cause.
Common mistakes
- Using `traceback.extract_tb` without filtering the last entry, which returns all frames.
- Assuming `tb_frame` is always available; it is only valid while the exception is being handled.
- Forgetting that `sys.exc_info()` returns a tuple; unpacking it into `exc_type, exc_value, tb` is required.
Variations
- Use `traceback.extract_tb(tb)[-1]` to get a `FrameSummary` with file, line, and function in one step.
- Use `inspect.trace()` inside the exception handler to retrieve a list of frame records.
Real-world use cases
- Custom logging that captures only the root cause location for alerts and dashboards.
- Building a debugger that jumps directly to the line that raised an uncaught exception.
- Enriching error reports in a web framework by attaching the innermost stack frame to structured logs.
Sponsored
More from Errors & debugging
- Catch RecursionError and Fail Gracefully in Python easy
- Catch ValueError and print friendly message in Python easy
- Collect Multiple Validation Errors in Python Before Raising medium
- Handle ValueError and ZeroDivisionError in Python with try except easy
- How to Add a Correlation ID to Logging Records in Python medium
- How to Assert Preconditions with Descriptive Messages in Python easy
Keep learning
Related tutorials and quizzes for this topic.