PYTHON / CHAPTER 13
Exceptions and resource boundaries
AdvancedHandle expected failures without hiding programming defects.
By the end of this chapter
- Catch specific exceptions near recovery policy
- Separate parsing from domain validation
- Use with for deterministic resource cleanup
The idea
Exceptions transfer control from a failing operation to a matching handler. Catch only failures you can meaningfully handle. Converting text to an integer may raise ValueError, while a programming mistake elsewhere should usually remain visible. Keep the try block narrow so an unrelated error is not mistaken for bad input. Domain validation still follows successful parsing: an integer can be syntactically valid but outside the accepted range.
Resources such as files need cleanup even when a later operation fails. A with statement delegates acquisition and release to a context manager, allowing cleanup on both ordinary completion and exceptions. Do not suppress failures merely to make a program appear successful. Prefer a documented return value for expected absence and a clear exception for a violated contract.
def nonnegative_count(text):
try:
value = int(text)
except ValueError as error:
raise ValueError("Count must be an integer") from error
if value < 0:
raise ValueError("Count must be nonnegative")
return value
print(nonnegative_count("12"))12
Conversion and range validation establish different parts of the contract. Chaining the conversion error preserves diagnostic context without changing successful results.
Try it yourself
Parse a list of count strings and return separate accepted values and rejected original strings without hiding unrelated exceptions.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
Open Python coding challengesCHECK YOUR UNDERSTANDING