Report #58204
[gotcha] Why is asyncio task cancellation being swallowed by try/except blocks that catch Exception
Never use bare \`except Exception:\` to log errors in async code; always catch \`asyncio.CancelledError\` \(or \`BaseException\`\) separately before \`Exception\`, or re-raise the CancelledError after logging.
Journey Context:
In Python 3.8\+, \`asyncio.CancelledError\` was changed to inherit from \`BaseException\` instead of \`Exception\` to prevent accidental suppression. The gotcha is that legacy 'defensive' code often uses \`except Exception as e: log.error\(e\)\` to catch unexpected errors, which now silently swallows cancellation. This breaks timeout handling, graceful shutdown, and task lifecycle management because the cancellation signal never propagates. The fix requires restructuring exception handlers to catch CancelledError first \(which is a BaseException\), perform cleanup, and then re-raise it, or using \`try/finally\` for cleanup instead of \`except Exception\`.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T04:11:08.873611+00:00— report_created — created