diff --git a/CHANGES/3628.bugfix b/CHANGES/3628.bugfix new file mode 100644 index 00000000000..22be2a07d27 --- /dev/null +++ b/CHANGES/3628.bugfix @@ -0,0 +1 @@ +Close session created inside ``aiohttp.request`` when unhandled exception occurs diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b92e8ab4faf..a007c730cc4 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -198,6 +198,7 @@ Rafael Viotti Raúl Cumplido Required Field Robert Lu +Robert Nikolich Roman Podoliaka Samuel Colvin Sean Hunt diff --git a/aiohttp/client.py b/aiohttp/client.py index f42ff68ad7c..c911bf48b1f 100644 --- a/aiohttp/client.py +++ b/aiohttp/client.py @@ -992,8 +992,13 @@ def __init__(self, self._session = session async def __aenter__(self) -> ClientResponse: - self._resp = await self._coro - return self._resp + try: + self._resp = await self._coro + except BaseException: + await self._session.close() + raise + else: + return self._resp async def __aexit__(self, exc_type: Optional[Type[BaseException]], diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index eb5943271eb..139f3869c71 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -2346,6 +2346,24 @@ async def handler(request): assert resp.status == 200 +async def test_aiohttp_request_ctx_manager_close_sess_on_error( + ssl_ctx, aiohttp_server) -> None: + async def handler(request): + return web.Response() + + app = web.Application() + app.router.add_get('/', handler) + server = await aiohttp_server(app, ssl=ssl_ctx) + + cm = aiohttp.request('GET', server.make_url('/')) + + with pytest.raises(aiohttp.ClientConnectionError): + async with cm: + pass + + assert cm._session.closed + + async def test_aiohttp_request_ctx_manager_not_found() -> None: with pytest.raises(aiohttp.ClientConnectionError):