Errors & try/except
- Catch specific exceptions with
try/exceptblocks - Raise your own exceptions with
raise - Use
finallyfor cleanup that must always run - Read Python tracebacks to diagnose bugs faster
Bare except: clauses hide KeyboardInterrupt and SystemExit — a classic reason CI jobs won't die on Ctrl-C. Sentry, structlog, and every FastAPI exception handler depend on precise exception hierarchies and raise ... from err chaining.
except Exception:swallowing errors without logging — always log or re-raise; silent failures rot codebases.- Losing traceback context by re-raising as
raise NewError(str(e))— useraise NewError(...) from einstead. - Putting cleanup in
exceptinstead offinally— cleanup won't run on the happy path.
Python raises exceptions when something goes wrong. You can catch them.
The pattern
try:
risky()
except SomeError as e:
handle(e)
finally:
cleanup()
Best practices
- Catch the narrowest exception you can. Bare
except:hides real bugs. - Don't catch what you can't handle. Letting an error bubble up is often the right call.
- Use
finally:for cleanup that must run either way.
Try it
- Add a check for negative
band raise aValueError. - Wrap the calls in a
tryand print every error you get.
3 graded exercises
Write the code, click Check. We’ll tell you exactly what to fix.
- Exercise 1
Write a function
safe_int(s)that returnsint(s), or returns0if the conversion raisesValueError. Then printsafe_int("42")andsafe_int("abc"). Expected outputs:42then0. - Exercise 2
Write
checked_divide(a, b)that returnsa / b, raisesValueError("cannot divide by zero")whenb == 0, and lets other errors bubble up. Then wrapchecked_divide(10, 0)in atry/exceptand print the caught message. - Exercise 3
Given
pairs = [(10, 2), (5, 0), (8, 4), (7, "x")], loop through and print each division result, or the error message for any pair that fails. Expected output includes5.0, an error for the zero,2.0, and a TypeError message.