tenacity icon indicating copy to clipboard operation
tenacity copied to clipboard

Shold not retry asyncio.CancelledError

Open KKomarov opened this issue 5 years ago • 1 comments

We should not retry CanceledError exceptions because it can lead to a severe bug when canceled coroutine will continue running in the background because retry stops it to cancel.

"suppressing cancellation completely is not common and is actively discouraged" cancel()

Here is the test. Should raise concurrent.futures._base.CancelledError after 1 second. Instead, it raises tenacity.RetryError after 5 seconds

import tenacity
import asyncio


async def test_retry_cancelled():
	@tenacity.retry(stop=tenacity.stop_after_delay(5))
	async def some_work():
		print('starting work')
		await asyncio.sleep(1)
		await asyncio.sleep(1)
		raise Exception('wow!')

	fut = asyncio.ensure_future(some_work())
	await asyncio.sleep(1)
	fut.cancel()
	await fut


asyncio.get_event_loop().run_until_complete(test_retry_cancelled())

KKomarov avatar Jul 30 '19 15:07 KKomarov

Since Python 3.8, asyncio.CancelledError became a BaseException (not Exception), your example works as expected in Python 3.8 (raising cancellation error after 1 second). Though, we need to add a separate CancelledError handling for Python 3.7 or older.

achimnol avatar Apr 20 '20 00:04 achimnol