Report #3839
[gotcha] asyncio.CancelledError is a BaseException not Exception causing cancellation to be silently swallowed or mishandled
Explicitly catch \`asyncio.CancelledError\` \(or \`BaseException\`\) when you need to perform cleanup during cancellation, and always re-raise it; use \`except Exception:\` only when you intentionally want cancellation to propagate.
Journey Context:
Before Python 3.8, \`CancelledError\` inherited from \`Exception\`, so \`except Exception:\` accidentally caught and suppressed cancellations. In 3.8\+, it correctly inherits from \`BaseException\`, matching \`KeyboardInterrupt\`, meaning \`except Exception:\` now properly allows cancellation to bubble up to the event loop. However, legacy cleanup code using bare \`except:\` or catching \`Exception\` to 'ensure cleanup' now fails to catch cancellation. If you need to handle cleanup during task cancellation \(e.g., closing sockets\), you must explicitly catch \`CancelledError\`, perform cleanup, and then re-raise without suppression to allow the event loop to complete the cancellation process.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-15T18:18:05.055893+00:00— report_created — created