Skip to content

[PR #11100/947247fd backport][3.13] Fix spurious "Future exception was never retrieved" warnings for connection lost errors #11102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES/11100.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed spurious "Future exception was never retrieved" warnings for connection lost errors when the connector is not closed -- by :user:`bdraco`.

When connections are lost, the exception is now marked as retrieved since it is always propagated through other means, preventing unnecessary warnings in logs.
6 changes: 6 additions & 0 deletions aiohttp/client_proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ def connection_lost(self, exc: Optional[BaseException]) -> None:
),
original_connection_error,
)
# Mark the exception as retrieved to prevent
# "Future exception was never retrieved" warnings
# The exception is always passed on through
# other means, so this is safe
with suppress(Exception):
self.closed.exception()

if self._payload_parser is not None:
with suppress(Exception): # FIXME: log this somehow?
Expand Down
19 changes: 19 additions & 0 deletions tests/test_client_proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,3 +247,22 @@ async def test_connection_lost_sets_transport_to_none(loop, mocker) -> None:
proto.connection_lost(OSError())

assert proto.transport is None


async def test_connection_lost_exception_is_marked_retrieved(
loop: asyncio.AbstractEventLoop,
) -> None:
"""Test that connection_lost properly handles exceptions without warnings."""
proto = ResponseHandler(loop=loop)
proto.connection_made(mock.Mock())

# Simulate an SSL shutdown timeout error
ssl_error = TimeoutError("SSL shutdown timed out")
proto.connection_lost(ssl_error)

# Verify the exception was set on the closed future
assert proto.closed.done()
exc = proto.closed.exception()
assert exc is not None
assert "Connection lost: SSL shutdown timed out" in str(exc)
assert exc.__cause__ is ssl_error
Loading