diff --git a/CHANGES/2423.bugfix b/CHANGES/2423.bugfix new file mode 100644 index 00000000000..08823f4f69f --- /dev/null +++ b/CHANGES/2423.bugfix @@ -0,0 +1 @@ +Fix connector convert OSError to ClientConnectorError diff --git a/aiohttp/connector.py b/aiohttp/connector.py index e70072148aa..47f8f3fb95b 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -785,6 +785,13 @@ def _create_direct_connection(self, req): sslcontext = self._get_ssl_context(req) fingerprint, hashfunc = self._get_fingerprint_and_hashfunc(req) + try: + hosts = yield from self._resolve_host(req.url.raw_host, req.port) + except OSError as exc: + # in case of proxy it is not ClientProxyConnectionError + # it is problem of resolving proxy ip itself + raise ClientConnectorError(req.connection_key, exc) from exc + hosts = yield from self._resolve_host(req.url.raw_host, req.port) for hinfo in hosts: @@ -938,6 +945,10 @@ def path(self): @asyncio.coroutine def _create_connection(self, req): - _, proto = yield from self._loop.create_unix_connection( - self._factory, self._path) + try: + _, proto = yield from self._loop.create_unix_connection( + self._factory, self._path) + except OSError as exc: + raise ClientConnectorError(req.connection_key, exc) from exc + return proto diff --git a/tests/test_connector.py b/tests/test_connector.py index 68167174e68..2970a9aba8e 100644 --- a/tests/test_connector.py +++ b/tests/test_connector.py @@ -9,6 +9,7 @@ import ssl import tempfile import unittest +import uuid from unittest import mock import pytest @@ -18,7 +19,7 @@ from aiohttp import client, helpers, web from aiohttp.client import ClientRequest from aiohttp.connector import Connection, _DNSCacheTable -from aiohttp.test_utils import unused_port +from aiohttp.test_utils import make_mocked_coro, unused_port @pytest.fixture() @@ -507,6 +508,19 @@ def test_tcp_connector_dns_throttle_requests_cancelled_when_close( yield from f +def test_dns_error(loop): + connector = aiohttp.TCPConnector(loop=loop) + connector._resolve_host = make_mocked_coro( + raise_exception=OSError('dont take it serious')) + + req = ClientRequest( + 'GET', URL('http://www.python.org'), + loop=loop, + ) + with pytest.raises(aiohttp.ClientConnectorError): + loop.run_until_complete(connector.connect(req)) + + def test_get_pop_empty_conns(loop): # see issue #473 conn = aiohttp.BaseConnector(loop=loop) @@ -1281,6 +1295,34 @@ def handler(request): assert r.status == 200 +@pytest.mark.skipif(not hasattr(socket, 'AF_UNIX'), + reason="requires unix socket") +def test_unix_connector_not_found(loop): + connector = aiohttp.UnixConnector('/' + uuid.uuid4().hex, loop=loop) + + req = ClientRequest( + 'GET', URL('http://www.python.org'), + loop=loop, + ) + with pytest.raises(aiohttp.ClientConnectorError): + loop.run_until_complete(connector.connect(req)) + + +@pytest.mark.skipif(not hasattr(socket, 'AF_UNIX'), + reason="requires unix socket") +def test_unix_connector_permission(loop): + loop.create_unix_connection = make_mocked_coro( + raise_exception=PermissionError()) + connector = aiohttp.UnixConnector('/' + uuid.uuid4().hex, loop=loop) + + req = ClientRequest( + 'GET', URL('http://www.python.org'), + loop=loop, + ) + with pytest.raises(aiohttp.ClientConnectorError): + loop.run_until_complete(connector.connect(req)) + + def test_default_use_dns_cache(loop): conn = aiohttp.TCPConnector(loop=loop) assert conn.use_dns_cache diff --git a/tests/test_proxy.py b/tests/test_proxy.py index 9a0380f520f..ab123c05a56 100644 --- a/tests/test_proxy.py +++ b/tests/test_proxy.py @@ -215,7 +215,7 @@ def _test_connect_request_with_unicode_host(self, Request_mock): Request_mock.assert_called_with(mock.ANY, mock.ANY, "xn--9caa.com:80", mock.ANY, loop=loop) - def test_proxy_connection_error(self): + def test_proxy_dns_error(self): connector = aiohttp.TCPConnector(loop=self.loop) connector._resolve_host = make_mocked_coro( raise_exception=OSError('dont take it serious'))