Advanced

Reading a stack trace

A crash printed twenty lines and I read from the top. The answer is at the bottom, and the useful line is the first one that is yours. Read a trace bottom-up and stop at your code.

What you will see

''

About 2 min of reading

Quick check

Before this new lesson, one small question about the lesson you just finished. Recall it, do not look it up.

Try It

Read a crash trace bottom-up and jump to the first frame that is your code.

1

A crash in your code that calls a helper. The trace prints the path.

def save(user): return user["name"] save({})

Before you run it, say out loud what it will print. Then open the answer.

What it prints
Traceback (most recent call last): File "main.py", line 4, in save({}) File "main.py", line 2, in save return user["name"] KeyError: 'name'
2

The bottom line is the error: KeyError 'name'. The frame above it is your save function at line 2. That is where to look.

def save(user): return user.get("name", "") save({})

Before you run it, say out loud what it will print. Then open the answer.

What it prints
''
Do not read a trace top-down. The top is the entry point, the bottom is the crash. The line you act on is the first frame that is yours, nearest the bottom.

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

The crash and its reason are at the bottom, the frames above are the call path innermost-first, and the first frame that is yours is where to look.
1 Read the last line for the error
↓
2 Frames above are the call path
↓
3 Innermost frame is nearest the crash
↓
4 First of your frames is the line
Why this works
Bottom-up, stop at yours

A stack trace is the crash at the bottom and the call path above it, innermost frame first. Read the last line for the what, then scan up for the first frame that belongs to your code. That line number is where you put the print or the breakpoint.

Library frames are noise

Frames inside a library tell you it was called, not that it is wrong. Unless the library itself is the suspect, skip those frames and go to the first one that is yours. This is why the trace is read from the bottom, not the top.

Examples

The bottom is the error

KeyError: 'name'

The last line is the error and its reason. Everything above is the path that led there. Start at the bottom to know what happened, then walk up to find where.

The frames above

  File "app.py", line 12, in save
  File "db.py", line 40, in write

Each block is one call on the path, innermost first. The frame is a function that was running when the error happened. Read them as a trail from the crash back to the entry point.

Stop at your line

  File "app.py", line 12, in save
    user["name"]

The first frame that is your code, with the line shown, is where to look. The library frames above it are noise you can usually skip.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← Locking a fix in place
Previous Lesson
Locking a fix in place
Next Lesson
Testing the rule, not the table
Testing the rule, not the table →