Understanding Exceptions and Tracebacks
Try/except structures prevent program crashes by catching exceptions and executing recovery code when operations fail.
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 when the file cannot be accessed. Without error handling, the program crashes and displays a raw traceback. A try/except structure lets the program anticipate the failure, provide useful feedback, and stop cleanly instead of leaving the user confused.
File opening is a common point of failure, so open() is often placed inside a try block when the program depends on the file being available.
The Try/Except Path
The try block contains the operation that may fail. If open() succeeds, the file object is assigned to fhand, the except block is skipped, and the program continues to the loop that counts lines beginning with Subject. If open() raises a FileNotFoundError, Python immediately stops executing the try block and jumps to the matching except block. The statements after the try/except structure do not run if the except block calls exit().
| File exists and can be opened | File cannot be opened |
|---|---|
| open() succeeds | open() raises an exception |
| fhand receives the file object | Python leaves the try block |
| except is skipped | except runs recovery code |
| The line-counting loop runs | A message is printed and exit() stops the program |
The two control-flow paths after the user enters a filename
Writing the Recovery Path
Recovery code belongs in the except block. In this file-opening pattern, it should tell the user that the file could not be opened and identify the filename involved. Calling exit() afterward is important when the file is required for the rest of the program: it prevents later code from attempting to use an unopened file.
If the user enters missing.txt and that file does not exist, the except block prints:
File cannot be opened: missing.txtThe recovery path is not merely a replacement for the failed open() call. It also prevents the rest of the program from using a file object that was never successfully opened.
Tracebacks and User Messages
A raw traceback is a technical error display produced when the file operation fails without error handling. It contains internal details that can confuse most users. The except block gives the program control over what the user sees. A message such as File cannot be opened: missing.txt identifies both the problem and the filename, making it more useful than the raw traceback.
Mistakes to Avoid
Common mistake Putting open() outside the try block
What it looks likefhand = open(filename) try: process(fhand)Why it failsThe file-opening operation can fail before execution reaches the try block, so the failure is not handled by that structure.
Do this insteadPlace the open() call inside the try block.
Common mistake Showing only the raw traceback to the user
What it looks likeThe program crashes when a requested file does not exist.
Why it failsThe traceback contains technical details that can confuse users and does not present the problem in a user-friendly way.
Do this insteadUse an except block to print a clear message that identifies the file that could not be opened.
Common mistake Continuing after a critical file-opening failure
What it looks likeThe except block prints an error but the program then reaches the line-counting loop.
Why it failsThe program may attempt to use a file that was never successfully opened.
Do this insteadCall exit() in the except block when the file is required for the remaining operations.
Common mistake Assuming every entered filename is valid
What it looks likeThe program expects the user's filename to exist without checking for failure.
Why it failsA file may not exist or may not be accessible, so the
open()operation may fail.Do this insteadTreat file opening as a potential point of failure and provide a recovery path.
Practice the Control Flow
A program asks the user for a filename and then counts lines beginning with Subject. Describe what happens in order when the user enters a filename that does not exist. Include the role of open(), the except block, the user-facing message, exit(), and the code after the try/except structure.
Hints
- Start at the
open()call inside the try block. - Identify the exception raised when the file does not exist.
- Explain why the loop and final print statement do not execute after
exit().
Tracing a missing filename
The user enters missing.txt, and that file does not exist. What path does the program take?
- 11. Begin the try block
The program reaches the
open()call while attempting to open the filename entered by the user. - 22. Raise the exception
Because the file does not exist,
open()raises aFileNotFoundError. - 33. Jump to except
Python stops executing the try block and transfers control to the except block.
- 44. Give feedback
The program prints File cannot be opened:
missing.txt, identifying both the failure and the filename. - 55. Exit
The call to
exit()terminates the program cleanly, so the later line-counting loop and result print do not execute.
The program handles the failure with a clear message and does not continue toward operations that require an opened file.
Key Takeaways
- 1Opening a file is a potential point of failure because the requested file may not exist or may not be accessible.
- 2A try block contains the operation that may fail, while the except block contains recovery code.
- 3When
open()raisesFileNotFoundError, Python leaves the try block and runs the matching except block. - 4A user-friendly message that includes the filename is more helpful than a raw traceback.
- 5Calling
exit()after a critical file-opening failure prevents later code from attempting to use an unopened file.
At a glance
- Use try/except when a file operation may fail.
- Put
open()inside the try block so a failed file opening can be handled. - Use the except block to provide a clear message that identifies the problem and filename.
- Call
exit()after a critical failure so the program does not continue toward file-dependent code. - A handled exception produces more useful user feedback than a raw traceback.