Issue 28274: asyncio does not call exception handler if task stored (original) (raw)
I found a very strange bug in asyncio where whether exception handlers are called depends on whether a task is stored.
To illustrate, the following code works as expected, printing out that it made it to the exception handler:
import asyncio async def run(): raise RuntimeError def exception_handler(loop, context): print('Made it to exception handler.') loop = asyncio.get_event_loop() loop.set_exception_handler(exception_handler) loop.create_task(run()) loop.run_forever()
However, if you take that exact same code but store the task that is returned from create_task, the exception handler will NOT be called:
import asyncio async def run(): raise RuntimeError def exception_handler(loop, context): print('Made it to exception handler.') loop = asyncio.get_event_loop() loop.set_exception_handler(exception_handler) task = loop.create_task(run()) loop.run_forever()
This is completely bizarre, and I have been unable to track down the reason.
In the first case, once the loop has run the task it no longer has a reference to it, and it gets GCed. The del method of the task calls your exception handler. In the second case, you have a reference to it, so del does not get called.
If you want the exception to be realized in the second case, you have to yield from it somewhere in your program.