"asyncio.gather return_exceptions: Stop Losing Results"

"One coroutine fails and asyncio.gather return_exceptions is the fix — without it you lose every result and get phantom \"exception was never retrieved\" warnings. Here's the repair."

What the error looks like You fan out four HTTP fetches with asyncio.gather , one of them hits a bad upstream — and instead of three good results plus one error, you get a traceback, an empty results list, and a cryptic warning at shutdown. Run this: import asyncio async def fetch(n): await asyncio.sleep(0.2) if n == 1: raise ValueError("fetch(1): 503 from upstream") if n == 3: raise ConnectionError("fetch(3): connection reset by peer") return f"data-{n}" async def main(): results = await asyncio.gather(*(fetch(i) for i in range(4))) print("results:", results) # never reached asyncio.run(main()) Output: Traceback (most recent call last): File "demo.py", line 12, in main results = await asyncio.gather(*(fetch(i) for i in range(4))) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "demo.py", line 6, in fetch raise ValueError("fetch(1): 503 from upstream") ValueError: fetch(1): 503 from upstream Future exception was never retrieved future: <Future finished exception=ConnectionError(&#x27;fetch(3): connection reset&#x27;)> Three casualties from one failure: the ValueError propagates and kills your await , the three *successful* results are gone with it, and the ConnectionError from fetch(3) surfaces later as a Future exception was never retrieved warning because nothing ever collected it. If your fetches write to a database or a log, that warning is the only trace you&#x27;ll ever see of the second failure. Last updated: 2026-10-05 Why asyncio.gather return_exceptions matters Here&#x27;s the root cause, in two sentences: with the default return_exceptions=False , the first raised exception is immediately propagated to whoever awaits the gather , and your results list never materializes. That&#x27;s the whole bug — everything else is fallout. Now the part most…

Explore