Python Tutorial: Using Try/Except Blocks for Error Handling
Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Use try/except to replace user-facing tracebacks with controlled, readable error messages.
Briefing
Python’s try/except structure lets developers replace ugly, user-facing tracebacks with controlled, readable error handling—while still catching only the failures they actually expect. The tutorial starts by attempting to open a misspelled file name, producing Python’s long traceback with details like the line number and “file not found.” That output is valuable during development, but it’s not appropriate for end users. Wrapping the risky file operation in a try block and handling failures in an except block allows the program to print a custom message such as “Sorry, this file does not exist,” keeping the experience clean and intentional.
A key lesson is that exception handling should be specific, not blanket. Using a broad “except Exception” catches many different problems, including ones that aren’t really about missing files. The tutorial demonstrates this by first causing a “file not found” scenario, then changing the file name to be correct and introducing a different error (a bad variable assignment). With a general exception handler in place, the code still prints the same “file does not exist” message—even though the failure is actually a NameError. Switching the handler to “except FileNotFoundError” restores correctness: the missing-file case is caught and handled, while unrelated errors fall through to Python’s default traceback so they can be diagnosed.
The tutorial also shows how to handle multiple exception types safely. When adding a more general “except Exception” alongside a specific “except FileNotFoundError,” the more specific handler must come first. Otherwise, the general handler intercepts everything and the specific branch never runs.
Beyond try and except, the tutorial breaks down two additional clauses that often clarify program flow. The else clause runs only when the try block completes without raising an exception. That makes it a good place for “success-only” work—like reading and closing a file after confirming it opened correctly—rather than mixing it into the try block where it might accidentally be executed under failure conditions. The finally clause runs regardless of success or failure, making it ideal for cleanup tasks. The example uses a print statement to show that finally executes both when the file operation succeeds (else runs first) and when an exception occurs (else is skipped but finally still runs). This pattern maps directly to real resource management, such as closing database connections.
Finally, the tutorial demonstrates that exceptions don’t have to originate from Python’s runtime. Developers can raise their own exceptions with the raise keyword based on custom conditions. An example checks for a specific file name (“corrupt file.txt”) and manually raises an exception, which then routes into the existing except handling logic. When the condition isn’t met, the normal file-reading path runs and finally still performs cleanup. Together, these patterns provide a structured way to handle expected errors, surface unexpected ones, and guarantee resource release.
Cornell Notes
Try/except in Python turns unpredictable failures into predictable behavior. The tutorial shows how opening a missing file normally produces a long traceback, but wrapping the operation in try and catching FileNotFoundError lets the program show a custom, user-friendly message. It also warns against overly broad except Exception handlers, since they can mask unrelated bugs (like a NameError) and incorrectly label them as missing files. The else clause runs only when no exception occurs, making it suitable for success-only logic like reading and closing a file. The finally clause runs no matter what, making it the right place for cleanup such as closing resources. The tutorial also demonstrates raising exceptions manually with raise to enforce custom error conditions.
Why does catching FileNotFoundError matter more than using a generic except Exception?
What’s the practical difference between the else and finally clauses?
How should multiple except blocks be ordered?
When is it appropriate to print a custom message versus printing the caught exception itself?
How can code raise its own exceptions in Python?
Review Questions
- What bug can occur when you use except Exception for a case that should only handle FileNotFoundError?
- In what scenarios should cleanup logic go in finally rather than else?
- Why does the order of except clauses matter when both specific and general exceptions are present?
Key Points
- 1
Use try/except to replace user-facing tracebacks with controlled, readable error messages.
- 2
Catch only the exceptions you expect (e.g., FileNotFoundError) to avoid masking unrelated bugs.
- 3
Place specific except clauses before general ones (like except Exception) so the right handler runs.
- 4
Use else for success-only logic that should run only when the try block completes without errors.
- 5
Use finally for cleanup that must happen whether the operation succeeds or fails.
- 6
You can raise exceptions manually with raise to enforce custom error conditions and route them through existing handlers.