Writing raise followed by an exception type and message creates and immediately throws an exception, interrupting normal execution and searching up the call stack for a matching except clause. Inside an except block, a bare raise with no arguments re-raises the exception currently being handled, preserving its original traceback — useful when you want to log or react to an error but still let it propagate. Chaining with `from` explicitly links a new exception to the one that caused it, which shows up clearly in the traceback as the original being the direct cause of the new one.
1Understanding raise Keyword
Writing raise followed by an exception type and message creates and immediately throws an exception, interrupting normal execution and searching up the call stack for a matching except clause. Inside an except block, a bare raise with no arguments re-raises the exception currently being handled, preserving its original traceback — useful when you want to log or react to an error but still let it propagate. Chaining with from explicitly links a new exception to the one that caused it, which shows up clearly in the traceback as the original being the direct cause of the new one.
Use a bare raise, with no arguments, to re-raise the currently-handled exception unchanged, rather than raising the caught exception object again explicitly, which subtly resets part of the traceback information.
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
return age
try:
set_age(-5)
except ValueError as e:
print(e)2Practical Example
Here is a real-world application of raise Keyword showing how it is used in production Python code.
def load_config():
try:
return int("not-a-number")
except ValueError as e:
raise RuntimeError("Failed to load config") from e
try:
load_config()
except RuntimeError as e:
print(e)
print(type(e.__cause__))3Best Practices
Follow these guidelines when working with raise Keyword:
1. Raise specific, meaningful built-in exception types (or your own custom ones) instead of a generic Exception, so callers can catch precisely what they expect
2. Use a bare raise inside except to re-propagate an exception after logging or partial handling, instead of raising the captured exception object again
3. Use raise NewError(...) from original_error when wrapping a low-level exception in a higher-level one, so the original cause remains visible in the traceback
Tip: Use a bare raise, with no arguments, to re-raise the currently-handled exception unchanged, rather than raising the caught exception object again explicitly, which subtly resets part of the traceback information.
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
return age
try:
set_age(-5)
except ValueError as e:
print(e)