You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Old way:
- exceptions and regular returns from main were captured, then
re-raised/returned from init, then captured again, then
re-raised/returned from run()
- exceptions in system tasks were converted into
TrioInternalErrors (one-at-a-time, using MultiError.filter()),
except for a whitelist of types (Cancelled, KeyboardInterrupt,
GeneratorExit, TrioInternalError), and then re-raised in the init
task.
- exceptions in the run loop machinery were caught in run(), and
converted into TrioInternalErrors (if they weren't already).
New way:
- exceptions and regular returns from main are captured, and then
re-raised/returned from run() directly
- exceptions in system tasks are allowed to propagate naturally into
the init task
- exceptions in the init task are re-raised out of the run loop
machinery
- exceptions in the run loop machinery are caught in run(), and
converted into TrioInternalErrors (if they aren't already).
This needs one new special case to detect when spawning the main task
itself errors, and treating that as a regular non-TrioInternalError,
but otherwise it simplifies things a lot. And, it removes 2
unnecessary traceback frames from every trio traceback.
Removing the special case handling for some exception types in system
tasks did break a few tests. It's not as bad as it seems though:
- Cancelled was allowed through so it could reach the system nursery's
__aexit__; that still happens. But now if it's not caught there, it
gets converted into TrioInternalError instead of being allowed to
escape from trio.run().
- KeyboardInterrupt should never happen in system tasks anyway; not
sure why we had a special case to allow this.
- GeneratorExit should never happen; if it does, it's probably because
things blew up real good, and then the system task coroutine got
GC'ed, and called coro.close(). In this case letting it escape is the
right thing to do; coro.close() will catch it. In other cases,
letting it escape and get converted into a TrioInternalError is
fine.
- Letting TrioInternalError through works the same as before.
Also, if multiple system tasks crash, we now get a single
TrioInternalError with the original MultiError as a __cause__, rather
than a MultiError containing multiple TrioInternalErrors. This is
probably less confusing, and it's more compatible with the python-triogh-611
approach to things.
0 commit comments