python runtime_error ai_generated true

asyncio.exceptions.CancelledError: CancelledError not caught in gather

ID: python/asyncio-gather-exception-handling

Also available as: JSON · Markdown · 中文
80%Fix Rate
86%Confidence
0Evidence
2024-08-18First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
3.8 active
3.9 active

Root Cause

When using asyncio.gather() with return_exceptions=False (default), an exception in one task cancels others, and CancelledError may propagate unexpectedly.

generic

中文

当使用 asyncio.gather() 且 return_exceptions=False(默认)时,一个任务中的异常会取消其他任务,并且 CancelledError 可能意外传播。

Workarounds

  1. 90% success Use return_exceptions=True to handle exceptions gracefully
    results = await asyncio.gather(task1, task2, return_exceptions=True)
    for r in results:
        if isinstance(r, Exception):
            # handle
  2. 85% success Catch CancelledError explicitly in each coroutine
    async def safe_coro():
        try:
            await something()
        except asyncio.CancelledError:
            # cleanup and re-raise if needed
            raise

Dead Ends

Common approaches that don't work:

  1. Wrapping each task in try-except without re-raising 50% fail

    If the task is cancelled externally, CancelledError may still be raised and not caught by a general except.

  2. Using asyncio.shield() on all tasks 40% fail

    shield() prevents cancellation but may cause tasks to run indefinitely if not managed.