diff --git a/CHANGES/12136.bugfix.rst b/CHANGES/12136.bugfix.rst new file mode 100644 index 00000000000..14ad7edf326 --- /dev/null +++ b/CHANGES/12136.bugfix.rst @@ -0,0 +1,2 @@ +``ClientConnectorCertificateError.os_error`` no longer raises :exc:`AttributeError` +-- by :user:`themylogin`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 7c5613648ca..487691f688f 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -392,6 +392,7 @@ Vladimir Kamarzin Vladimir Kozlovski Vladimir Rutsky Vladimir Shulyak +Vladimir Vinogradenko Vladimir Zakharov Vladyslav Bohaichuk Vladyslav Bondar diff --git a/aiohttp/client_exceptions.py b/aiohttp/client_exceptions.py index af83a42705e..3b66c7fdcd2 100644 --- a/aiohttp/client_exceptions.py +++ b/aiohttp/client_exceptions.py @@ -342,10 +342,21 @@ class ClientConnectorSSLError(*ssl_error_bases): # type: ignore[misc] class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore[misc] """Response certificate error.""" + _conn_key: ConnectionKey + def __init__( - self, connection_key: ConnectionKey, certificate_error: Exception + # TODO: If we require ssl in future, this can become ssl.CertificateError + self, + connection_key: ConnectionKey, + certificate_error: Exception, ) -> None: - self._conn_key = connection_key + if isinstance(certificate_error, cert_errors + (OSError,)): + # ssl.CertificateError has errno and strerror, so we should be fine + os_error = certificate_error + else: + os_error = OSError() + + super().__init__(connection_key, os_error) self._certificate_error = certificate_error self.args = (connection_key, certificate_error) diff --git a/tests/test_client_exceptions.py b/tests/test_client_exceptions.py index ed87b6d50f1..a7bf4db05ef 100644 --- a/tests/test_client_exceptions.py +++ b/tests/test_client_exceptions.py @@ -201,6 +201,15 @@ def test_str(self) -> None: " [Exception: ('Bad certificate',)]" ) + def test_oserror(self) -> None: + certificate_error = OSError(1, "Bad certificate") + err = client.ClientConnectorCertificateError( + connection_key=self.connection_key, certificate_error=certificate_error + ) + assert err.os_error == certificate_error + assert err.errno == 1 + assert err.strerror == "Bad certificate" + class TestServerDisconnectedError: def test_ctor(self) -> None: