-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Description
🐞 Describe the bug
await ClientResponse.json() raises asyncio.exceptions.TimeoutError when the ClientSession has already ended instead of raising an error indicating that reading the response body may be unsuccessful with an ended ClientSession. ClientResponse.json gets stuck in an endless loop, trying to read the response body that it cannot, until the TimeoutError is raised.
💡 To Reproduce
Minimum code to reproduce (ran on Windows), may need to run several times to get it to hang and raise error.
from __future__ import annotations
import asyncio
import aiohttp
async def send() -> aiohttp.ClientResponse:
timeout = aiohttp.ClientTimeout(total=30) # type: ignore
async with aiohttp.ClientSession(timeout=timeout) as session:
response = await session.get('https://jsonplaceholder.typicode.com/todos/')
return response
async def main():
response = await send()
print('Received response...')
data = await response.json()
print(data)
if __name__ == "__main__":
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
asyncio.run(main())💡 Expected behavior
ClientResponse should raise an error that the indicates the ClientSession has closed and cannot read the response body successfully.
📋 Logs/tracebacks
Received response...
Traceback (most recent call last):
File "C:\Python38\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Python38\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\user\Desktop\test_data\web_test\__main__.py", line 19, in <module>
asyncio.run(main())
File "C:\Python38\lib\asyncio\runners.py", line 43, in run
return loop.run_until_complete(main)
File "C:\Python38\lib\asyncio\base_events.py", line 616, in run_until_complete
return future.result()
File "C:\Users\user\Desktop\test_data\web_test\__main__.py", line 14, in main
data = await response.json()
File "C:\Users\user\Desktop\test_data\.venv\lib\site-packages\aiohttp\client_reqrep.py", line 1092, in json
await self.read()
File "C:\Users\user\Desktop\test_data\.venv\lib\site-packages\aiohttp\client_reqrep.py", line 1032, in read
self._body = await self.content.read()
File "C:\Users\user\Desktop\test_data\.venv\lib\site-packages\aiohttp\streams.py", line 370, in read
block = await self.readany()
File "C:\Users\user\Desktop\test_data\.venv\lib\site-packages\aiohttp\streams.py", line 392, in readany
await self._wait("readany")
File "C:\Users\user\Desktop\test_data\.venv\lib\site-packages\aiohttp\streams.py", line 306, in _wait
await waiter
File "C:\Users\user\Desktop\test_data\.venv\lib\site-packages\aiohttp\helpers.py", line 656, in __exit__
raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError📋 Your version of the Python
$ python --version
Python 3.8.5📋 Your version of the aiohttp/yarl/multidict distributions
$ python -m pip show aiohttp
Name: aiohttp
Version: 3.7.4.post0
Summary: Async http client/server framework (asyncio)
Home-page: https://github.com/aio-libs/aiohttp
Author: Nikolay Kim
Author-email: fafhrd91@gmail.com
License: Apache 2
Location: c:\users\user\desktop\test_data\.venv\lib\site-packages
Requires: chardet, typing-extensions, attrs, async-timeout, yarl, multidict
Required-by: $ python -m pip show multidict
Name: multidict
Version: 5.1.0
Summary: multidict implementation
Home-page: https://github.com/aio-libs/multidict
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: c:\users\user\desktop\test_data\.venv\lib\site-packages
Requires:
Required-by: yarl, aiohttp$ python -m pip show yarl
Name: yarl
Version: 1.6.3
Summary: Yet another URL library
Home-page: https://github.com/aio-libs/yarl/
Author: Andrew Svetlov
Author-email: andrew.svetlov@gmail.com
License: Apache 2
Location: c:\users\user\desktop\test_data\.venv\lib\site-packages
Requires: idna, multidict
Required-by: aiohttp