-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CancelledError suppressed where it should not #8174
Comments
This is something we just fixed in aiohttp-sse. Should probably have a look through all our code to find similar issues. As in aiohttp-sse, I'd be fine with a fix that only works on Python 3.11, as it's awkward to fix on older versions and has been like that forever: https://github.com/aio-libs/aiohttp-sse/pull/459/files Further information: https://superfastpython.com/asyncio-task-cancellation-best-practices/#Practice_1_Do_Not_Consume_CancelledError |
I have read your patch ( https://github.com/aio-libs/aiohttp-sse/pull/459/files ). However I am not sure it is safe. It assumes that, if the current task is cancelled, then it is due to the same exception we are just processing in the I wrote initially that I thought that my code was safer. But, reading your code that seems very logical and simple (even if requiring python >= 3.11), I am not sure. Maybe they are equivalent technically. That would be two versions available for this patch:
|
I suggest reading the linked article. The current task is cancelling because it is being asked to cancel (i.e. cancelled from outside the task). In this situation, the cancellation should be propagated. If the inner task has been cancelled and we are receiving the exception as it bubbles up, then the current task is not cancelling(). There are no assumptions in that logic. To avoid maintaining rather verbose, complex code, I'd personally prefer to just fix this on 3.11+. I think you're the first user to actually report this, so I'm not too worried about the behaviour existing in the oldest versions of Python for a little while longer, there are similar issues in asyncio itself in those versions regardless. |
I agree. Your code is much (much) more maintainable and forward-looking. |
Describe the bug
The
ClientRequest.close
method suppressesasyncio.CancelledError
:aiohttp/aiohttp/client_reqrep.py
Line 680 in 006fbe0
This is incorrect as this error does not always bubble up from the inside _writer task. It can also bubble down from the outside (if the task executing this
ClientRequest.close
call is canceled by another party). Suppressing the later case makes the aiohttp client unreliable as it may not honor cancellation demands from the outside.To Reproduce
Read the code above. A specific test case may be built.
Expected behavior
A specific utility function shall be used, to be able to catch only CancelledError bubbling up from the inside _writer task and let all other exceptions (whether bubbling down or up) go through.
As an example, here is such a utility method:
This code may seem complex, but it does cover all the edge cases as specified. This is very close to the code of
asyncio.gather
, just faster and much simpler as we are waiting on a single awaitable here.It can be used this way to wrap the _writer field:
in place of
aiohttp/aiohttp/client_reqrep.py
Line 661 in 006fbe0
have
Logs/tracebacks
Python Version
aiohttp Version
multidict Version
yarl Version
OS
MacOS Sonoma 14.2.1
Related component
Client
Additional context
No response
Code of Conduct
The text was updated successfully, but these errors were encountered: