Exception chaining enables users to see if an exception was triggered by another exception (see https://www.python.org/dev/peps/pep-3134/[PEP-3134]). Exceptions are chained using either of the following syntax:
* ``++raise NewException() from chained_exception++``
It is also possible to erase a chaining by setting ``++new_exception.__cause__ = None++`` or using ``++except ... from None++`` (see https://www.python.org/dev/peps/pep-0409/[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
* PEP 3134 – https://www.python.org/dev/peps/pep-3134/[Exception Chaining and Embedded Tracebacks]
* PEP 409 – https://www.python.org/dev/peps/pep-0409/[Suppressing exception context]
* PEP 352 - https://www.python.org/dev/peps/pep-0352/#exception-hierarchy-changes[Required Superclass for Exceptions]