Skip to content
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

[PR #10551/d067260d backport][3.11] Re-raise OSError as ClientConnectionError when failing to explicitly close connector socket #10561

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
1 change: 1 addition & 0 deletions CHANGES/10551.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The connector now raises :exc:`aiohttp.ClientConnectionError` instead of :exc:`OSError` when failing to explicitly close the socket after :py:meth:`asyncio.loop.create_connection` fails -- by :user:`bdraco`.
5 changes: 4 additions & 1 deletion aiohttp/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -1138,7 +1138,10 @@ async def _wrap_create_connection(
# Will be hit if an exception is thrown before the event loop takes the socket.
# In that case, proactively close the socket to guard against event loop leaks.
# For example, see https://github.com/MagicStack/uvloop/issues/653.
sock.close()
try:
sock.close()
except OSError as exc:
raise client_error(req.connection_key, exc) from exc

async def _wrap_existing_connection(
self,
Expand Down
27 changes: 27 additions & 0 deletions tests/test_connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,33 @@ async def test_tcp_connector_closes_socket_on_error(
await conn.close()


async def test_tcp_connector_closes_socket_on_error_results_in_another_error(
loop: asyncio.AbstractEventLoop, start_connection: mock.AsyncMock
) -> None:
"""Test that when error occurs while closing the socket."""
req = ClientRequest("GET", URL("https://127.0.0.1:443"), loop=loop)
start_connection.return_value.close.side_effect = OSError(
1, "error from closing socket"
)

conn = aiohttp.TCPConnector()
with (
mock.patch.object(
conn._loop,
"create_connection",
autospec=True,
spec_set=True,
side_effect=ValueError,
),
pytest.raises(aiohttp.ClientConnectionError, match="error from closing socket"),
):
await conn.connect(req, [], ClientTimeout())

assert start_connection.return_value.close.called

await conn.close()


async def test_tcp_connector_server_hostname_default(
loop: Any, start_connection: mock.AsyncMock
) -> None:
Expand Down
Loading