== Why is this an issue?

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++``
* ``++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 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

[source,python]
----
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

[source,python]
----
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
----


== Resources

* 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]
* Python documentation - https://docs.python.org/3/library/exceptions.html[Built-in Exceptions]

ifdef::env-github,rspecator-view[]

'''
== Implementation Specification
(visible only on this page)

=== Message

Replace this expression of type X with an exception or None


=== Highlighting

* In a "raise X from Y" statement:
** highlight Y
* In an "myexception.__cause__ = Y" statement:
** highlight Y


endif::env-github,rspecator-view[]
