Debugging Tracebacks
flowchart TD A["Traceback (most recent call last):"] --> B["outermost frame -- where the call chain began"] B --> C["... intermediate frames ..."] C --> D["innermost frame -- the line that raised"] D --> E["ExceptionType: message"] E --> F["1. read the type and message FIRST"] F --> G["2. find the lowest frame in YOUR code"] G --> H["3. walk up only if that frame looks correct"] I["'During handling ... another exception occurred'"] --> J["two tracebacks: the second one is the cause"] K["'The above exception was the direct cause'"] --> L["raise ... from -- read the FIRST block"]
A repeatable debugging process
Section titled “A repeatable debugging process”When you see an exception:
- Read the last line (exception type + message)
- Go to the line number where it occurred
- Check the types/values of variables
- Create a minimal reproduction
- Fix and re-run
Example traceback
Section titled “Example traceback”def avg(nums):
return sum(nums) / len(nums)
print(avg([]))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 zeroFix approach
Section titled “Fix approach”- The list is empty, so
len(nums)is 0. - Decide policy: return
None, raise a clear error, or handle with default.
def avg(nums):
if len(nums) == 0:
raise ValueError("avg() requires at least one number")
return sum(nums) / len(nums)
print(avg([10, 20]))Quick tip: print types
Section titled “Quick tip: print types”value = "10"
print(type(value), value)
print(int(value))Optional: use the debugger
Section titled “Optional: use the debugger”Python has a built-in debugger.
import pdb
x = 10
pdb.set_trace()
print(x)Useful commands inside the debugger:
nnextsstep intop varprint variableccontinue
Check yourself
Section titled “Check yourself”-
In a Python traceback, which line tells you where the exception was RAISED?
The header says 'most recent call last'. Frames are printed in call order, so the bottom frame is the innermost one.
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.
-
A traceback runs through twenty frames of a web framework. What is the fastest way in?
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.
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.
-
Two tracebacks are printed with 'During handling of the above exception, another exception occurred' between them. What does that mean?
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.
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.
-
Why does `raise ... from None` not actually erase the original exception?
Verified: after `from None`, `__cause__` is None but `__context__` still holds the original. A logger walking the chain can still find it.
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.
🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – Read a Traceback
Section titled “Exercise 1 – Read a Traceback”Exercise 2 – Traceback Module
Section titled “Exercise 2 – Traceback Module”Exercise 3 – Get Traceback as String
Section titled “Exercise 3 – Get Traceback as String”pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading