🎓 A1Learner
🔍

Python The traceback Module

The traceback module turns a traceback into text. The text can be stored instead of shown on the screen.

Capture a traceback as text

format_exc() returns the traceback as a string. Its last line names the error and its message.

import traceback

try:
    10 / 0
except ZeroDivisionError:
    text = traceback.format_exc()
    lines = text.strip().splitlines()
    print(lines[-1])

Log an error the proper way

A logger is an object that writes log messages. logger.exception adds the current traceback to the message for free.

import logging

logger = logging.getLogger("demo")
try:
    int("abc")
except ValueError:
    logger.exception("Load failed")

Walk the frames

extract_tb() lists the frames behind an error. The last frame is where the error was raised.

import traceback

def boom():
    raise ValueError("Boom")

try:
    boom()
except ValueError as err:
    frames = traceback.extract_tb(err.__traceback__)
    print(frames[0].name)
    print(frames[-1].name)

Read a chained traceback

A chained traceback mentions the direct cause. Its last line still belongs to the newest error.

import traceback

try:
    try:
        int("abc")
    except ValueError as err:
        raise ValueError("Bad age") from err
except ValueError:
    text = traceback.format_exc()
    print("direct cause" in text)
    print(text.strip().splitlines()[-1])

Example

import traceback

def add(a, b):
    return a + b

def crash():
    return 1 / 0

def parse(text):
    return int(text)

results = []
traces = []

def run(name, func, *args):
    try:
        result = func(*args)
        results.append(f"{name}: {result}")
    except Exception:
        results.append(f"{name}: failed")
        traces.append(traceback.format_exc())

run("add", add, 2, 3)
run("crash", crash)
run("parse", parse, "abc")

for line in results:
    print(line)
print(len(traces))
for text in traces:
    print(text.strip().splitlines()[-1])

Key points

  • Traceback text: the full report Python prints for an error, held as a string
  • Use traceback.format_exc() inside an except block to get the current traceback as text
  • Frame: one step in the call chain that led to an error
  • Use traceback.extract_tb() to walk the saved frames of an error
  • Use logger.exception(message) inside an except block to log a message with its traceback
  • The text can also be searched and reported later.

In this example, the runner tries three small jobs. The add job succeeds and its result joins the results list. The crash job divides by zero and fails. The parse job gets bad text and fails too. For each failure, run stores the full formatted traceback in the traces list. The main code prints one result line per job. It then prints how many tracebacks were stored. Last it prints only the final line of each stored traceback. Those lines are stable, while file paths inside the full text are not.

Note

Tracebacks contain file paths and line numbers, which differ per machine, so print only their stable last line.

Try it Yourself

Edit the code, then press Run.

Running is simulated · Python Playground

Exercise

What does traceback.format_exc() return?