How Does Exception Handling Work in Python?
Learn how Python exception handling works with try, except, else, and finally, plus custom exceptions and chaining, explained for interview prep.
Expected Interview Answer
Python handles runtime errors using try/except blocks: code that might fail goes in `try`, the recovery logic goes in matching `except` clauses, and optional `else`/`finally` blocks run on success or always, respectively.
When an error occurs inside a `try` block, Python raises an exception object and searches downward for a matching `except` clause by exception type. If found, that block runs and execution continues after the whole construct; if not found, the exception propagates up the call stack. `else` runs only when no exception occurred, and `finally` always runs, making it ideal for cleanup like closing files or releasing locks. You can also raise your own exceptions with `raise`, chain them with `raise ... from ...`, and define custom exception classes by subclassing `Exception`.
- Separates error-handling logic from normal logic
- Prevents a single failure from crashing the whole program
- finally guarantees cleanup regardless of outcome
- Custom exceptions communicate domain-specific failures clearly
- Exception chaining preserves the original error context
AI Mentor Explanation
Exception handling is like a batsman's pre-planned response to different deliveries: the try is facing the ball, an except clause is the specific shot played when a bouncer comes rather than a yorker, and finally is walking back to the crease and resetting stance no matter how the ball turned out. A raised exception is like an umpire's decision that stops play until it is addressed.
Step-by-Step Explanation
Step 1
try wraps risky code
Code that might raise an error is placed inside the try block.
Step 2
except catches by type
Each except clause matches a specific exception class (or a tuple of classes).
Step 3
else runs on success
The optional else block executes only if no exception was raised.
Step 4
finally always runs
Cleanup code in finally executes whether or not an exception occurred, even during a return.
Step 5
raise and custom exceptions
You can raise built-in or custom Exception subclasses, optionally chaining with `raise ... from err`.
What Interviewer Expects
- Explains try/except/else/finally roles precisely
- Knows exceptions are matched by type, most specific first
- Mentions finally always executes, even with return statements
- Can define and raise a custom exception class
- Understands exception propagation up the call stack
Common Mistakes
- Using a bare `except:` that swallows all errors including KeyboardInterrupt
- Forgetting that finally runs even after a return in try
- Catching Exception too broadly instead of specific types
- Not knowing about exception chaining with `raise ... from`
Best Answer (HR Friendly)
“Exception handling lets a Python program deal with unexpected errors gracefully instead of crashing. You put risky code in a try block, handle specific problems in except blocks, and use a finally block for cleanup steps that must always run, like closing a file.”
Code Example
def read_config(path):
try:
with open(path) as f:
data = f.read()
except FileNotFoundError as e:
print(f"Config missing: {e}")
return None
except PermissionError as e:
raise RuntimeError("Cannot read config") from e
else:
print("Loaded config successfully")
return data
finally:
print("Config load attempt finished")Follow-up Questions
- What is the difference between except Exception and a bare except?
- How does raise ... from ... affect the traceback?
- When would you define a custom exception class?
- Does finally run if the try block contains a return statement?
- What is the exception hierarchy rooted at BaseException?
MCQ Practice
1. Which block always executes regardless of an exception?
finally always runs, whether or not an exception was raised, making it ideal for cleanup.
2. When does the else block in a try statement run?
else runs only when the try block completed without raising an exception.
3. How do you create a custom exception?
Custom exceptions are created by subclassing Exception (or a more specific built-in exception).
Flash Cards
What does try/except do? — Runs risky code and catches specific exception types if raised.
When does finally run? — Always, whether or not an exception occurred.
When does else run? — Only when the try block succeeds without raising.
How do you chain exceptions? — Use `raise NewError(...) from original_error` to preserve context.