Report #57101
[gotcha] asyncio.wait\_for cancels the wrapped task on timeout but the task may swallow CancelledError and complete silently
Ensure wrapped tasks do not catch and suppress \`asyncio.CancelledError\` \(allow it to propagate\), or check the task's \`cancelled\(\)\` status after catching \`TimeoutError\`
Journey Context:
When \`asyncio.wait\_for\(coroutine, timeout\)\` expires, it cancels the underlying Task. If that Task has a \`try/except\` block that catches generic \`Exception\` or specifically \`CancelledError\` and swallows it \(does not re-raise\), the Task completes successfully instead of being marked cancelled. \`wait\_for\` then raises \`TimeoutError\`, but the task ran to completion despite the cancellation request, causing resource leaks or partial state changes. The fix is to never suppress \`CancelledError\` \(PEP 3156 requirement\) or to check \`task.cancelled\(\)\` after catching \`TimeoutError\` to verify if the cancellation was honored. Alternative approaches using \`shield\(\)\` prevent the cancellation from reaching the task, but then the task runs indefinitely even after timeout.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T02:19:53.080262+00:00— report_created — created