jd / jd/tenacity

retry_if_not_exception_type swallows asyncio.CancelledError

Open
#529 1 comment 2 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
8.8k
Forks
359
Avg merge
1m
Merged PRs (30d)
1

Description

# Problem

When using `retry_if_no_exception_type` to avoid retries for a specific exception, this causes `asyncio.CancelledError` to be caught and retried. This is contra-typical behaviour, as `CancelledError` does not typically cause a retry to occur in other scenarios. This is because task cancellation is not typically a retry case, and allow these errors to bubble up enables cancellation utilities like `asyncio.wait_for` to work as excpected.

# Steps to reproduce

Observe the behaviour as expected with this:

```
from tenacity import retry, wait_fixed, stop_after_attempt
import asyncio

@retry(
wait=wait_fixed(10),
stop=stop_after_attempt(2),
reraise=True,
)
async def test():
print("Sleeping")
await asyncio.sleep(3)
print("Done")

await asyncio.wait_for(test(), 1) # Expected to cancel after 1s
```

The output here is:
```
Sleeping
CancelledError Traceback (most recent call last)
... (traceback)
```

We see incorrect behaviour in this case:

```
from tenacity import retry, wait_fixed, stop_after_attempt, retry_if_not_exception_type
import asyncio

@retry(
wait=wait_fixed(10),
stop=stop_after_attempt(2),
reraise=True,
retry=retry_if_not_exception_type(ValueError)
)
async def test_with_issue():
print("Sleeping")
await asyncio.sleep(3)
print("Done")

await asyncio.wait_for(test_with_issue(), 1) # Expected to cancel after 1s
```

The output here is:
```
Sleeping
Sleeping
Done
```

Here we see the retry occurring. We expect no retry to occur, and for the behaviour in this case to be the same as the former.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.