Skip to content

Commit 497df2e

Browse files
[PR #11100/947247fd backport][3.12] Fix spurious "Future exception was never retrieved" warnings for connection lost errors (#11101)
Co-authored-by: J. Nick Koston <[email protected]>
1 parent d4e62ef commit 497df2e

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

CHANGES/11100.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed spurious "Future exception was never retrieved" warnings for connection lost errors when the connector is not closed -- by :user:`bdraco`.
2+
3+
When connections are lost, the exception is now marked as retrieved since it is always propagated through other means, preventing unnecessary warnings in logs.

aiohttp/client_proto.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ def connection_lost(self, exc: Optional[BaseException]) -> None:
9797
),
9898
original_connection_error,
9999
)
100+
# Mark the exception as retrieved to prevent
101+
# "Future exception was never retrieved" warnings
102+
# The exception is always passed on through
103+
# other means, so this is safe
104+
with suppress(Exception):
105+
self.closed.exception()
100106

101107
if self._payload_parser is not None:
102108
with suppress(Exception): # FIXME: log this somehow?

tests/test_client_proto.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,22 @@ async def test_connection_lost_sets_transport_to_none(loop, mocker) -> None:
247247
proto.connection_lost(OSError())
248248

249249
assert proto.transport is None
250+
251+
252+
async def test_connection_lost_exception_is_marked_retrieved(
253+
loop: asyncio.AbstractEventLoop,
254+
) -> None:
255+
"""Test that connection_lost properly handles exceptions without warnings."""
256+
proto = ResponseHandler(loop=loop)
257+
proto.connection_made(mock.Mock())
258+
259+
# Simulate an SSL shutdown timeout error
260+
ssl_error = TimeoutError("SSL shutdown timed out")
261+
proto.connection_lost(ssl_error)
262+
263+
# Verify the exception was set on the closed future
264+
assert proto.closed.done()
265+
exc = proto.closed.exception()
266+
assert exc is not None
267+
assert "Connection lost: SSL shutdown timed out" in str(exc)
268+
assert exc.__cause__ is ssl_error

0 commit comments

Comments
 (0)