Exception chaining enables users to see if an exception was triggered by another exception (see PEP-3134). Exceptions are chained using either of the following syntax:
-
raise NewException() from chained_exception
-
new_exception.__cause__ = chained_exception
It is also possible to erase a chaining by setting new_exception.__cause__ = None
or using except ... from None
(see PEP-409).
Chaining will fail and raise a TypeError
if something else than None
or a valid exception, i.e. an instance of
BaseException
or of a subclass, is provided.
Noncompliant Code Example
class A:
pass
try:
raise ValueError("orig")
except ValueError as e:
new_exc = TypeError("new")
new_exc.__cause__ = A() # Noncompliant
raise new_exc
try:
raise ValueError("orig")
except ValueError as e:
raise TypeError("new") from "test" # Noncompliant
Compliant Solution
try:
raise ValueError("orig")
except ValueError as e:
new_exc = TypeError("new")
new_exc.__cause__ = None # Ok
raise new_exc
try:
raise ValueError("orig")
except ValueError as e:
new_exc = TypeError("new")
new_exc.__cause__ = e # Ok
raise new_exc
try:
raise ValueError("orig")
except ValueError as e:
raise TypeError("new") from None # Ok
try:
raise ValueError("orig")
except ValueError as e:
raise TypeError("new") from e # Ok
See