Raise and re-raise exceptions in Python
Choose appropriate Python exception types, preserve causes with raise from, and re-raise failures without relying on assertions for input validation.
Use raise with an exception instance, such as raise ValueError("Amount must be positive"). Choose a type that tells the caller what failed, and include enough context to make the message useful.
Validate a value
def validate_payment(amount, payment_type):
if payment_type not in ("Visa", "Mastercard"):
raise ValueError(f"Unsupported payment type: {payment_type}")
if amount <= 0:
raise ValueError("Amount must be positive")
try:
validate_payment(100, "Discover")
except ValueError as error:
print(f"Invalid payment: {error}")
This is a small validation example, not a complete payment implementation. Type, currency, precision, and authorization requirements belong in the actual payment code.
Select a meaningful type
| Exception | Typical meaning |
|---|---|
ValueError |
An accepted type contains an invalid value |
TypeError |
An unsupported argument type |
KeyError |
A mapping key is missing |
IndexError |
A sequence index is out of range |
FileNotFoundError |
A requested file or directory does not exist |
PermissionError |
An operation lacks the required access |
RuntimeError |
A failure not covered by a more specific category |
NotImplementedError |
A required operation has not been implemented |
For an application-specific category, define a subclass of Exception and raise an instance of it.
Preserve the underlying cause
def read_count(text):
try:
return int(text)
except ValueError as error:
raise RuntimeError("Invalid count in configuration") from error
from error explicitly records the cause. The traceback can show both the low-level conversion error and your higher-level explanation. from None suppresses display of the implicit context; use it only when that presentation is intentional.
Re-raise the active exception
import logging
logger = logging.getLogger(__name__)
def load_count(text):
try:
return read_count(text)
except Exception:
logger.exception("Unable to load count")
raise
A bare raise re-raises the exception currently being handled. With no active exception, it raises RuntimeError. Avoid logging the same failure repeatedly at every layer if an outer handler already records it.
FAQ
Can I raise the class itself? raise ValueError is allowed and constructs an exception without a message. This differs from a bare raise, which re-raises an active exception.
Why not use assert for validation? Assertions can be removed under python -O. Use explicit conditionals and raise for checks that must run in production.
Can I raise a string? No. Python requires an exception instance or a class derived from BaseException. Application exceptions should normally derive from Exception.
References
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan