Change sub-class of NameResolutionError to NewConnectionError
This solves various problems:
* Adding `NameResolutionError` is no longer a breaking change
* Retries are supported again
* `ProxyError` is raised again for all proxy related errors
MODIFY
src/urllib3/connection.py
src/urllib3/connection.py
@@ -207,7 +207,7 @@ class HTTPConnection(_HTTPConnection):
socket_options=self.socket_options,
)
except socket.gaierror as e:
- raise NameResolutionError(self.host, e)
+ raise NameResolutionError(self.host, self, e)
except SocketTimeout:
raise ConnectTimeoutError(
self,

MODIFY
src/urllib3/connectionpool.py
src/urllib3/connectionpool.py
@@ -30,7 +30,6 @@ from .exceptions import (
InsecureRequestWarning,
LocationValueError,
MaxRetryError,
- NameResolutionError,
NewConnectionError,
ProtocolError,
ProxyError,
@@ -739,7 +738,6 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
SSLError,
CertificateError,
HTTPSProxyError,
- NameResolutionError,
) as e:
# Discard the connection for these exceptions. It will be
# replaced during the next _get_conn() call.
@@ -747,8 +745,6 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods):
new_e: Exception = e
if isinstance(e, (BaseSSLError, CertificateError)):
new_e = SSLError(e)
- elif isinstance(e, NameResolutionError):
- pass
elif isinstance(e, (OSError, NewConnectionError)) and self.proxy:
new_e = ProxyError("Cannot connect to proxy.", e)
elif isinstance(e, (OSError, HTTPException)):

MODIFY
src/urllib3/exceptions.py
src/urllib3/exceptions.py
@@ -184,6 +184,14 @@ class NewConnectionError(ConnectTimeoutError, HTTPError):
return self.conn
+class NameResolutionError(NewConnectionError):
+ """Raised when host name resolution fails."""
+
+ def __init__(self, host: str, conn: "HTTPConnection", reason: socket.gaierror):
+ message = f"Failed to resolve '{host}' ({reason})"
+ super().__init__(conn, message)
+
+
class EmptyPoolError(PoolError):
"""Raised when a pool runs out of connections and no more are allowed."""
@@ -379,11 +387,3 @@ class UnrewindableBodyError(HTTPError):
"""urllib3 encountered an error when trying to rewind a body"""
pass
-
-
-class NameResolutionError(HTTPError, socket.gaierror):
- """Raised when host name resolution fails."""
-
- def __init__(self, host: str, reason: socket.gaierror):
- message = f"Failed to resolve '{host}' ({reason})"
- HTTPError.__init__(self, message)

MODIFY
test/with_dummyserver/test_proxy_poolmanager.py
test/with_dummyserver/test_proxy_poolmanager.py
@@ -16,7 +16,7 @@ from urllib3.exceptions import (
ConnectTimeoutError,
HTTPSProxyError,
MaxRetryError,
- NameResolutionError,
+ ProxyError,
ProxySchemeUnknown,
ProxySchemeUnsupported,
SSLError,
@@ -146,7 +146,7 @@ class TestHTTPProxyManager(HTTPDummyProxyTestCase):
with pytest.raises(MaxRetryError) as e:
http.request("GET", f"{self.http_url}/")
- assert type(e.value.reason) == NameResolutionError
+ assert type(e.value.reason) == ProxyError
def test_https_conn_failed(self):
"""

Change sub-class of NameResolutionError to NewConnectionError

This solves various problems:

 * Adding `NameResolutionError` is no longer a breaking change
 * Retries are supported again
 * `ProxyError` is raised again for all proxy related errors