This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: asyncio does not call exception handler if task stored
Type: Stage: resolved
Components: asyncio Versions: Python 3.5
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: billyfoster, gvanrossum, r.david.murray, yselivanov
Priority: normal Keywords:

Created on 2016-09-25 18:37 by billyfoster, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (2)
msg277394 - (view) Author: Billy Foster (billyfoster) Date: 2016-09-25 18:37
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.
msg277396 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-09-25 19:21
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.
History
Date User Action Args
2022-04-11 14:58:37adminsetgithub: 72461
2016-09-25 19:21:46r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg277396

resolution: not a bug
stage: resolved
2016-09-25 18:37:27billyfostercreate