Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

asyncio: loop.run_until_complete(loop.create_task(f)) prints "Task exception was never retrieved" even though it clearly was propagated

For some reason this program prints the following warning:

Task exception was never retrieved
future: <Task finished coro=<coro() done, defined at /usr/lib64/python3.4/asyncio/coroutines.py:139> exception=SystemExit(2,)>

even though the exception is clearly retrieved and propagated, as caught SystemExit! is printed to the terminal, and process status code becomes 2.

The same thing happens with Python 2 and trollius.

Am I missing something?

#!/usr/bin/env python3

import asyncio

@asyncio.coroutine
def comain():
    raise SystemExit(2)

def main():
    loop = asyncio.get_event_loop()
    task = loop.create_task(comain())
    try:
        loop.run_until_complete(task)
    except SystemExit:
        print("caught SystemExit!")
        raise
    finally:
        loop.close()

if __name__ == "__main__":
    main()
like image 626
WGH Avatar asked Oct 27 '25 07:10

WGH


1 Answers

SystemExit seems to be a special case. If, for example, you raise and catch an Exception, you won't see any errors. The way around this seems to be to manually retrieve the exception using Task.exception():

import asyncio

@asyncio.coroutine
def comain():
    raise SystemExit(2)

def main():
    loop = asyncio.get_event_loop()
    task = loop.create_task(comain())
    try:
        loop.run_until_complete(task)
    except SystemExit:
        print("caught SystemExit!")
        task.exception()
        raise
    finally:
        loop.close()

if __name__ == "__main__":
    main()

EDIT

Actually, all BaseException subclasses will behave this way.

like image 132
Jashandeep Sohi Avatar answered Oct 29 '25 22:10

Jashandeep Sohi