Exception Handling
Raising Exceptions
Signaling errors with raise and re-raising
Interview: Error propagation — tests understanding of raise, re-raising, and when to use exceptions vs return codes
The raise statement is used to explicitly throw exceptions. Use it to signal errors, validate inputs, and propagate errors up the call stack. Python allows you to raise built-in exceptions or custom ones, and to re-raise caught exceptions to preserve the original traceback.
When to Raise
- Input validation: raise
ValueErrororTypeErrorfor invalid arguments - Business logic errors: raise custom exceptions for domain-specific failures
- Re-raising: catch, log/handle, then re-raise to let callers handle it too
- Preconditions: raise early to fail fast rather than producing bad results later
Re-raising Patterns
raise(bare): Re-raises the current exception with original tracebackraise NewError(...) from e: Chains a new exception with the original causeraise e: Re-raises but creates new traceback (loses original context)
Common Pitfall
Using raise e instead of bare raise loses the original traceback. Always use bare raise to re-raise the current exception.
Use Cases
Input validation at API boundaries and function entry points
Business logic errors (insufficient funds, duplicate entries)
Fail-fast patterns: raise early rather than producing bad data
Logging then re-raising for observability without swallowing errors
Retry logic: catch transient errors, re-raise after max retries
Common Mistakes
Using raise e instead of bare raise (loses original traceback)
Raising generic Exception instead of specific types
Not providing useful error messages in exceptions
Raising exceptions for expected conditions (use return values)
Forgetting that raise without arguments only works inside an except block