Understanding Python Errors and Tracebacks
The try/except structure catches errors in risky code (like opening files) and runs recovery code in the except block instead of crashing.
When File Assumptions Fail
A program that opens a file makes an assumption: the file exists and can be read. That assumption may be wrong when a user enters a filename that does not exist or types something that is not a real filename. Without protection, the program crashes and the user sees a confusing traceback. Python's try/except structure lets the program anticipate this predictable failure and respond with a helpful message instead.
The central decision is simple: put code that might fail in try, then decide in except whether the program can recover or must stop.
The Try and Except Path
The try block contains risky code, such as an operation that opens a file. If every statement in the try block succeeds, Python skips the except block and continues with the code after the complete try/except structure. If the try block fails, Python immediately jumps to the except block. The except block can print a helpful message and then either allow the program to continue or terminate it.
A Protected File Count
Suppose the program asks for a filename, opens that file, and counts lines beginning with Subject:. The file opening is the risky operation. The rest of the program depends on fhand being assigned a usable file object, so the program must decide what to do if opening the file fails.
fname = input("Enter the file name: ")
try:
fhand = open(fname)
except:
print("File cannot be opened:", fname)
exit()
count = 0
for line in fhand:
if line.startswith("Subject:"):
count = count + 1
print(count)- 1The program receives a filename and stores it in fname.
- 2Python attempts to open fname and assign the resulting file object to fhand.
- 3If the attempt fails, Python immediately enters except. The message is printed, and
exit()terminates the program. - 4If the attempt succeeds, except is skipped. The program sets count to zero and examines the file lines.
- 5Each line beginning with Subject: increases count by one.
- 6The final print statement displays the count only when the program reached that point.
- The input supplies the filename.
- The open operation is placed inside try because it might fail.
- If opening fails, except prints a helpful message and calls
exit(). - If opening succeeds, the program counts lines that start with Subject:.
Two Execution Traces
What do you think happens?
If the user enters mbox.txt and the file opens successfully, does the except block run?
Reveal answer
No, except is skipped when try succeeds.
With a valid filename such as mbox.txt, the file opens, fhand is assigned, and execution continues to the counting loop and the final print statement.
Valid filename
Trace the program when the user enters mbox.txt and the file opens successfully.
- 1Input
The user enters
mbox.txt. - 2Try
open(fname)succeeds, and fhand is assigned. - 3Except
The except block is skipped because no failure occurred.
- 4Counting
The program counts lines that start with Subject:.
- 5Output
The program prints the count of subject lines.
Execution continues normally after the try/except structure.
Invalid filename
Trace the program when the user enters na na boo boo and the file cannot be opened.
- 1Input
The user enters na na boo boo instead of a real filename.
- 2Try
The open operation fails.
- 3Jump
Python immediately jumps to the except block.
- 4Message
The program prints the helpful error message written in except.
- 5Exit
exit()terminates the program, so the counting loop and final print statement do not run.
The program handles the failure without showing the confusing traceback described in the unprotected case.
Recovery or Termination
Handling an error and ending a program are related but different actions. The except block is the recovery point: it can explain what went wrong and make a decision. Calling exit() is the termination choice. In the file-counting example, continuing is not useful after open fails because the remaining code depends on fhand being a valid file object. exit() stops the program immediately, before the loop and final print statement can run.
Mistakes with Error Handling
Common mistake Putting the file operation outside try
What it looks likefhand = open(fname) try: count = 0Why it failsThe risky operation is not protected, so a failure can occur before the except block can handle it.
Do this insteadPlace the open operation inside the try block.
Common mistake Assuming except runs after every try block
What it looks likeThe file opens successfully, but the programmer expects the error message to print anyway.
Why it failsWhen try succeeds, Python skips except entirely.
Do this insteadPut normal success-path work after the try/except structure.
Common mistake Continuing to use fhand after opening failed
What it looks likeThe program enters except but then proceeds to the counting loop.
Why it failsThe remaining program depends on fhand being a valid file object.
Do this insteadCall exit() when the failed open makes it impossible to continue.
Common mistake Giving the user no useful explanation
What it looks likeThe except block stops the program without printing a helpful message.
Why it failsThe user does not understand what went wrong.
Do this insteadPrint a clear error message in the except block before deciding whether to continue or exit.
Practice the Control Flow
Trace the protected file-counting program for two inputs: first mbox.txt when it opens successfully, and then na na boo boo when it cannot be opened. For each input, identify whether the except block runs, whether the counting loop runs, and whether the final print statement runs.
Hints
- Start by deciding whether
open(fname)succeeds. - A successful try skips except.
- A failed try jumps to except; if that block calls
exit(), later code does not run.
| Situation | Except runs? | Counting loop runs? | Program outcome |
|---|---|---|---|
| File opens successfully | No | Yes | The subject-line count is printed |
| File cannot be opened and except calls exit() | Yes | No | A helpful message is printed and the program ends |
Compare the two execution paths through the protected file operation.
Reliable File Failure Handling
Treat file opening as an operation that may fail, and protect it with try/except. In the except block, tell the user what went wrong. Then make an explicit control-flow decision: continue only if the rest of the program can work without the failed operation; otherwise call exit(). This produces a graceful failure instead of a crash followed by a confusing traceback.
Key Takeaways
- Place risky file operations such as
open()inside a try block. - If try succeeds, Python skips except and continues after the try/except structure.
- If try fails, Python immediately jumps to except, where the program can print a helpful message.
- Use
exit()to terminate the program when the failed file operation makes continuation impossible. - Recovering from an error means handling it; terminating with
exit()is one possible decision made during that handling.