Question
Python asyncio: handling exceptions in gather() - documentation unclear?
The documentation for asyncio.gather says that
If return_exceptions is
False
(default), the first raised exception is immediately propagated to the task that awaits ongather()
. Other awaitables in the aws sequence won’t be cancelled and will continue to run.
However, from a simple test it seems that if one of the tasks raises an exception when return_exceptions is False
, all other awaitable are cancelled (or to be more precise, in case the terminology is not clear to me, the other awaitables do not finish their job):
import asyncio
async def factorial(name, number, raise_exception=False):
# If raise_exception is True, will raise an exception when
# the loop counter > 3
f = 1
for i in range(2, number + 1):
print(f' Task {name}: Compute factorial({i})...')
if raise_exception and i > 3:
print(f' Task {name}: raising Exception')
raise Exception(f'Bad Task {name}')
await asyncio.sleep(1)
f *= i
print(f'==>> Task {name} DONE: factorial({number}) = {f}')
return f
async def main():
tasks = [factorial('A', 5), # this will not be finished
factorial('B', 10, raise_exception=True),
factorial('C', 2)]
try:
results = await asyncio.gather(*tasks)
print('Results:', results)
except Exception as e:
print('Got an exception:', e)
asyncio.run(main())
What this piece of code is doing, just to make it simpler, it defines 3 tasks and call asyncio.gather()
on them. One of the tasks raises an exception before one of the others is done, and this other task is not finished.
Actually, I cannot even make sense with what the documentations says - if an exception is raised and caught by the task awaiting on gather
, I would not even be able to get the returned results (even if the other task would, somehow, get done).
Am I missing anything, or is there a problem with the documentation?
This was tested with Python 3.7.2.