Skip to content

Debugging Tracebacks

diagram read a traceback from the bottom mermaid
The frames are printed in call order -- where it started at the top, where it exploded at the bottom -- and the exception itself is the last line. So the fastest way to read one is to start at the bottom, find the error type and the innermost frame, and only walk upwards if that frame is not yours.

When you see an exception:

  1. Read the last line (exception type + message)
  2. Go to the line number where it occurred
  3. Check the types/values of variables
  4. Create a minimal reproduction
  5. Fix and re-run
bug.py
def avg(nums):
    return sum(nums) / len(nums)
 
print(avg([]))
Traceback
Traceback (most recent call last):
  File "bug.py", line 4, in <module>
    print(avg([]))
  File "bug.py", line 2, in avg
    return sum(nums) / len(nums)
ZeroDivisionError: division by zero
  • The list is empty, so len(nums) is 0.
  • Decide policy: return None, raise a clear error, or handle with default.
fix.py
def avg(nums):
    if len(nums) == 0:
        raise ValueError("avg() requires at least one number")
    return sum(nums) / len(nums)
 
print(avg([10, 20]))
type_debug.py
value = "10"
print(type(value), value)
print(int(value))

Python has a built-in debugger.

pdb_example.py
import pdb
 
x = 10
pdb.set_trace()
print(x)

Useful commands inside the debugger:

  • n next
  • s step into
  • p var print variable
  • c continue
sketch Read a traceback from the bottom p5.js
The frames are printed in call order, so where it started is at the top and where it exploded is at the bottom, with the exception itself on the last line. Scanning upward from the bottom for the first frame in code you wrote is the fastest route to the mistake, because everything below that is usually a library doing what it was told.
pch.quizTag pch.quizDefaultTitle
  1. In a Python traceback, which line tells you where the exception was RAISED?

    pch.quizShowAnswer

    B — The last `File` line, just above the exception message — The header says 'most recent call last'. Frames are printed in call order, so the bottom frame is the innermost one.

  2. A traceback runs through twenty frames of a web framework. What is the fastest way in?

    pch.quizShowAnswer

    B — Read the exception line, then scan up for the lowest frame in your own code — Everything below your lowest frame is usually library code doing what it was told. The mistake is normally in your frame or in the arguments it passed.

  3. Two tracebacks are printed with 'During handling of the above exception, another exception occurred' between them. What does that mean?

    pch.quizShowAnswer

    B — The second happened while handling the first, and is often incidental — That phrasing means implicit chaining via `__context__`. 'The above exception was the direct cause' is the other one — deliberate chaining with `raise ... from`, where the first block is the story.

  4. Why does `raise ... from None` not actually erase the original exception?

    pch.quizShowAnswer

    B — It only suppresses the DISPLAY; `__context__` is still set — Verified: after `from None`, `__cause__` is None but `__context__` still holds the original. A logger walking the chain can still find it.

pch.coffeeTagline

pch.coffeeCta

pch.feedbackHeading

pch.feedbackSubheading