Skip to content

no-swallowed-asyncio-cancellation

Preserve cancellation when an async operation is cancelled.

Why

Returning or falling through after catching CancelledError can make cancelled work look successful and interfere with task groups and timeout shutdown. Child cancellation must be distinguished from cancellation of the caller.

Fix

Re-raise after cleanup. If child cancellation is an expected result, first propagate cancellation when asyncio.current_task().cancelling() is nonzero. Use an exact suppression for a documented boundary that deliberately consumes cancellation.

Examples

Before — flagged Cancellation becomes a successful return
worker.py
import asyncio
async def worker():
try:
await asyncio.sleep(10)
except asyncio.CancelledError:
return None
After — preferred Cleanup preserves cancellation
worker.py
import asyncio
async def worker():
try:
await asyncio.sleep(10)
except asyncio.CancelledError:
raise