Skip to content

await ClientResponse.json() raises TimeoutError when ClientSession is closed #5582

@joeriddles

Description

@joeriddles

🐞 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions