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)
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
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.
Input: The user enters mbox.txt.
Try: open(fname) succeeds, and fhand is assigned.
Except: The except block is skipped because no failure occurred.
Counting: The program counts lines that start with Subject:.
Output: 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.
Input: The user enters na na boo boo instead of a real filename.
Try: The open operation fails.
Jump: Python immediately jumps to the except block.
Message: The program prints the helpful error message written in except.
Exit: 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
Putting the file operation outside try
The risky operation is not protected, so a failure can occur before the except block can handle it.
Fix:
Place the open operation inside the try block.Assuming except runs after every try block
When try succeeds, Python skips except entirely.
Fix:
Put normal success-path work after the try/except structure.Continuing to use fhand after opening failed
The remaining program depends on fhand being a valid file object.
Fix:
Call exit() when the failed open makes it impossible to continue.Giving the user no useful explanation
The user does not understand what went wrong.
Fix:
Print 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.