Hi, I recently encountered a situation with asyncio where the stack
trace is getting truncated: an exception isn't getting chained as
expected.

I was able to reduce it down to the code below.

The reduced case seems like a pattern that can come up a lot, and I
wasn't able to find an issue on the CPython tracker, so I'm wondering
if I'm doing something wrong or if the behavior is deliberate.

The way I would describe it is that (at least in this case) awaiting
on a task that raises an exception doesn't set __context__ when
awaiting on the task inside an "except" block. Here is the code:

    import asyncio

    async def raise_error():
        raise RuntimeError('exception #2')

    async def main():
        try:
            raise RuntimeError('exception #1')
        except Exception:
            future = raise_error()
            # Uncommenting the next line makes exc.__context__ None.
            # future = asyncio.ensure_future(future)

            try:
                await future
            except Exception as exc:
                print(f'exc: {exc!r}, context: {exc.__context__!r}')
                raise

    asyncio.get_event_loop().run_until_complete(main())

Here is the output of the above, which works as expected:

exc: RuntimeError('exception #2',), context: RuntimeError('exception #1',)
Traceback (most recent call last):
  File "test.py", line 8, in main
    raise RuntimeError('exception #1')
RuntimeError: exception #1

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    asyncio.get_event_loop().run_until_complete(main())
  File "/.../python3.6/asyncio/base_events.py", line 466, in run_until_complete
    return future.result()
  File "test.py", line 15, in main
    await future
  File "test.py", line 4, in raise_error
    raise RuntimeError('exception #2')
RuntimeError: exception #2

And here is the unexpected output when the commented line is
uncommented (exception not getting chained):

exc: RuntimeError('exception #2',), context: None
Traceback (most recent call last):
  File "test.py", line 22, in <module>
    asyncio.get_event_loop().run_until_complete(main())
  File "/.../python3.6/asyncio/base_events.py", line 466, in run_until_complete
    return future.result()
  File "test.py", line 17, in main
    await future
  File "test.py", line 6, in raise_error
    raise RuntimeError('exception #2')
RuntimeError: exception #2

--Chris
_______________________________________________
Async-sig mailing list
[email protected]
https://mail.python.org/mailman/listinfo/async-sig
Code of Conduct: https://www.python.org/psf/codeofconduct/

Reply via email to