Basically I want:
await action1()
await action2()
return result
with a single timeout for both actions and - that's important - with an error message telling which action timed out.
For comparison, with just one action:
try:
await asyncio.wait_for(action(), timeout=1.0)
except asyncio.TimeoutError:
raise RuntimeError("Problem")
Now with two actions I have this and don't like it.
import asyncio
async def a2():
try:
await asyncio.sleep(1.0)
except asyncio.CancelledError:
raise RuntimeError("Problem 1") from None
try:
await asyncio.sleep(1.0)
except asyncio.CancelledError:
raise RuntimeError("Problem 2") from None
return True
async def test():
loop = asyncio.get_event_loop()
action_task = loop.create_task(a2())
# timeouts: 0.5 -> Problem1 exc; 1.5 -> Problem2 exc; 2.5 -> OK
try:
await asyncio.wait_for(action_task, timeout=0.5)
except asyncio.TimeoutError:
pass
result = await action_task
asyncio.get_event_loop().run_until_complete(test())
I find it really counter-intuitive to have:
except asyncio.TimeoutError:
pass
where timeout handling is the main functionality. Can you suggest a better way?