Description
Documentation
The tutorial's section on exception chaining (raise x from y
) currently claims:
Exception chaining happens automatically when an exception is raised inside an
except
orfinally
section.
While that is true, the semantics of automatically chained exceptions are different from ones explicitly chained with from
, which is also reflected in how their relation is described in the resulting error messages: Automatically chained exceptions are linked with
During handling of the above exception, another exception occurred:
while for explicitly chained exceptions it says
The above exception was the direct cause of the following exception:
That is not mentioned anywhere in the tutorial section, making the claim that "chaining happens automatically" by itself extremely misleading because it suggests to people they'll get the same result whether they chain explicitly with from
or not, which isn't the case. It's probably also confusing to those readers who give it a bit more thought, because the natural question to ask would be "Then why does from
exist at all if it happens automatically anyway?"
My suggestion would be to explain the semantic difference and the different resulting outputs in the tutorial section, e.g. like this:
A kind of exception chaining also happens automatically when an exception is raised inside an
except
orfinally
section, although in this case the statement linking the exceptions in the error message will be different:>>> try: ... func() ... except ConnectionError as exc: ... raise RuntimeError ... Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<stdin>", line 2, in func ConnectionError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeErrorAs can be seen from the output, an exception raised inside an exception handler but not explicitly chained with
from
represents an additional, possibly unrelated error that occurred during handling, while an explicitly chained exception represents a direct consequence of the caught exception.
Of course the phrasing isn't perfect but that can be fought over in a PR if you think the overall point of this issue is valid.
Related issues
- Clarify chaining exceptions in tutorial/errors.rst #86345 went in the same direction but was more about whether the underlying technical difference, specifically
__cause__
vs__context__
, should be explained.