Ensure mounted transports are closed even if main transport raises

When closing a client with proxy mounts, if the main transport's
close/exit raises an exception, the mounted transports would never
be cleaned up. This could lead to leaked connections.

Wrap the main transport cleanup in try/finally to ensure mounted
transports are always properly closed.
This commit is contained in:
Kadir Can Ozden 2026-02-20 03:35:18 +03:00
parent ae1b9f6623
commit ff7190eda0

View File

@ -1267,10 +1267,12 @@ class Client(BaseClient):
if self._state != ClientState.CLOSED:
self._state = ClientState.CLOSED
self._transport.close()
for transport in self._mounts.values():
if transport is not None:
transport.close()
try:
self._transport.close()
finally:
for transport in self._mounts.values():
if transport is not None:
transport.close()
def __enter__(self: T) -> T:
if self._state != ClientState.UNOPENED:
@ -1298,10 +1300,12 @@ class Client(BaseClient):
) -> None:
self._state = ClientState.CLOSED
self._transport.__exit__(exc_type, exc_value, traceback)
for transport in self._mounts.values():
if transport is not None:
transport.__exit__(exc_type, exc_value, traceback)
try:
self._transport.__exit__(exc_type, exc_value, traceback)
finally:
for transport in self._mounts.values():
if transport is not None:
transport.__exit__(exc_type, exc_value, traceback)
class AsyncClient(BaseClient):
@ -1982,10 +1986,12 @@ class AsyncClient(BaseClient):
if self._state != ClientState.CLOSED:
self._state = ClientState.CLOSED
await self._transport.aclose()
for proxy in self._mounts.values():
if proxy is not None:
await proxy.aclose()
try:
await self._transport.aclose()
finally:
for proxy in self._mounts.values():
if proxy is not None:
await proxy.aclose()
async def __aenter__(self: U) -> U:
if self._state != ClientState.UNOPENED:
@ -2013,7 +2019,9 @@ class AsyncClient(BaseClient):
) -> None:
self._state = ClientState.CLOSED
await self._transport.__aexit__(exc_type, exc_value, traceback)
for proxy in self._mounts.values():
if proxy is not None:
await proxy.__aexit__(exc_type, exc_value, traceback)
try:
await self._transport.__aexit__(exc_type, exc_value, traceback)
finally:
for proxy in self._mounts.values():
if proxy is not None:
await proxy.__aexit__(exc_type, exc_value, traceback)