Exceptions Basics
9 examples to get you started with Exceptions - 6 basic and 3 intermediate.
Prerequisites
- Python 3.14.0 installed.
- Exceptions inherit from
BaseException; catchExceptionin application code, notBaseException.
Basic Examples
1. try/except Specific Type
Catch only the failure you can handle.
def parse_port(text: str) -> int:
try:
port = int(text)
except ValueError:
raise ValueError(f"invalid port: {text!r}") from None
return port- Catch the narrowest exception type that fits.
- Re-raise with context when translating errors for callers.
from Nonesuppresses the original chain when it adds noise.
Related: Raising & Chaining - preserve tracebacks
2. else Clause
Run code only when no exception occurred in try.
def load_config(path: str) -> dict:
try:
f = open(path, encoding="utf-8")
except FileNotFoundError:
return {}
else:
with f:
import json
return json.load(f)elseavoids running success-only code insidetry(which would catch its exceptions too).- Keeps
exceptfocused on the open failure mode. - Pair with
withwhen the resource should close on success path.
Related: The logging Module - log missing config paths
3. finally Always Runs
Cleanup executes whether or not an exception fired.
lock_acquired = False
try:
lock_acquired = True # pretend acquire
print("critical section")
finally:
if lock_acquired:
print("release lock")finallyis for release/cleanup guarantees.- Do not return values from
finally- it overridestry/exceptreturns. - Prefer
withwhen the object supports context management.
Related: Context Managers as a Pattern - structured cleanup
4. Exception Hierarchy
Catch a base class to handle a family of errors.
try:
int("not-a-number")
except (ValueError, TypeError) as exc:
print(type(exc).__name__, exc)- Built-in hierarchy groups related failures (
OSErrorsubclasses). - Tuple in
exceptcatches multiple types. - Order handlers from specific to general when chaining
exceptblocks.
Related: Custom Exception Hierarchies - domain bases
5. Re-raise with bare raise
Preserve the original traceback inside an except block.
def process():
try:
risky()
except ValueError:
log("bad value") # pretend log
raise- Bare
raisere-propagates the active exception with stack intact. - Use when logging or enriching context before failure exits.
- Do not
raise excwith a stored variable unless you understand traceback binding.
Related: Raising & Chaining -
raise ... from
6. Exception Attributes
Many exceptions carry structured fields.
try:
open("/no/such/file.txt")
except FileNotFoundError as exc:
print(exc.errno, exc.filename)OSErrorsubclasses expose.errno,.filename,.strerror.- Read attributes for user-facing messages and metrics labels.
- Domain exceptions should follow the same pattern with custom fields.
Related: Custom Exception Hierarchies - design fields
Intermediate Examples
7. Context Manager Suppresses on Exit
Returning true from __exit__ suppresses exceptions (rare - use deliberately).
from contextlib import suppress
with suppress(FileNotFoundError):
print(open("optional.txt").read())
print("continues")contextlib.suppressdocuments intentional swallowing.- Never bare
except: passin application code. - Log suppressed errors when they indicate data issues, not optional files.
Related: Errors & Logging Best Practices - never swallow silently
8. Exception Groups Overview
Multiple errors can surface as one ExceptionGroup (3.11+).
def failing_tasks():
raise ExceptionGroup(
"batch failed",
[ValueError("a"), TypeError("b")],
)
try:
failing_tasks()
except* ValueError as eg:
print("value errors:", len(eg.exceptions))except*handles matching sub-exceptions inside a group.- Task groups and concurrent code may raise groups.
- See dedicated page for full
except*semantics.
Related: Exception Groups & except* - full guide
9. Log and Raise Pattern
Record context, then fail - do not swallow.
import logging
log = logging.getLogger(__name__)
def charge(amount: float) -> None:
if amount < 0:
log.error("invalid charge amount=%s", amount)
raise ValueError("amount must be non-negative")- Log at appropriate level before raising for operability.
- Include structured fields (
amount=%s) not f-strings in logging calls. - Callers still receive the exception for control flow.
Related: Structured & Contextual Logging - JSON fields
Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.