Report #62032
[gotcha] Why does my asyncio task not get cancelled even though I catch the CancelledError for cleanup?
Re-raise \`CancelledError\` after cleanup, or use \`try/finally\` instead of \`except\` for cleanup. Swallowing the exception signals successful completion to the event loop.
Journey Context:
When an \`asyncio\` task is cancelled, a \`CancelledError\` is injected at the next \`await\` point. If your code catches this with \`except Exception:\` or \`except CancelledError:\` to perform cleanup \(like closing a connection\), the exception is consumed. The event loop sees the task as completed successfully rather than cancelled, breaking structured concurrency assumptions. The fix is to use \`try/finally\` for cleanup \(which doesn't catch the exception\) or explicitly \`raise\` the \`CancelledError\` after cleanup. Note that in Python 3.8\+, \`CancelledError\` moved from \`Exception\` to \`BaseException\` hierarchy to prevent accidental catching by \`except Exception\`, but explicit catches still swallow it if not re-raised.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T10:36:18.836319+00:00— report_created — created