Closed dmoklaf closed 1 month ago
However, I am not familiar with the internals of the aiohttp libray, I am not sure if both methods need to be patched, one only or none (different fix needed).
Its likely both since the cancellation of the writer shouldn't be leaking upward
It looks like this refactoring would also allow to simplify the code of the write_bytes
method underlying the _writer
task:
https://github.com/aio-libs/aiohttp/blob/006fbe03fede4eaa1eeba7b8393cbf4d63cb44b6/aiohttp/client_reqrep.py#L557
This method catches CancelledError which would be useless with the new mechanism described above. Also, this method seems to catch other errors, but not completely. In some cases, it exposes itself to new exception being raised, e.g. in
and
So there seems to be an unconsistent mix of behaviors regarding exceptions handling/raising. But maybe connection management (ie detecting broken connections and bubbling up these I/O errors) make it necessary.
Reading the entire class, it looks like there is a lot of complexity around the _writer task to work around the various cases. Maybe all this _writer code could be simplified by using a clean single callback connected to the task, together with a Future, to handle properly the various task exit cases.
I am definitely not versed enough in this repository to guess what would be the correct change to perform to align all this on a single, simple behavior.
Describe the bug
I am using a large-scale crawler based on aiohttp client. Some old web servers break connections randomly when under load (hence this bug is difficult to reproduce). When they do, in rare cases, the aiohttp client emits a
CancelledError
. Investigating the code, I found where this is coming from: https://github.com/aio-libs/aiohttp/blob/006fbe03fede4eaa1eeba7b8393cbf4d63cb44b6/aiohttp/client_reqrep.py#L1020 https://github.com/aio-libs/aiohttp/blob/006fbe03fede4eaa1eeba7b8393cbf4d63cb44b6/aiohttp/client_reqrep.py#L1037These methods do not suppress the CancelledError that may be raised internally by the _writer (a task wrapping the write_bytes method). This task emits a CancelledError in very rare cases, when it is cancelled by the aiohttp internal machinery before having been truly started by the asyncio scheduler. In this case, none of the internal CancelledError try...except mechanisms it has are called, and the CancelledError, entirely technical to serve the internal aiohttp logic, bubbles up to the library caller.
To Reproduce
Difficult to reproduce (a large scale crawler is necessary to reach this error)
Expected behavior
The CancelledError, being purely internal, shall not bubble up to the library caller. It shall be intercepted in the 2 methods above.
To do so, a robust CancelledError suppression mechanism, as the one posted in #8174, can be used.
However, I am not familiar with the internals of the aiohttp libray, I am not sure if both methods need to be patched, one only or none (different fix needed).
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