diff --git a/CHANGES/9455.bugfix.rst b/CHANGES/9455.bugfix.rst new file mode 120000 index 0000000000..da8457a1de --- /dev/null +++ b/CHANGES/9455.bugfix.rst @@ -0,0 +1 @@ +9451.bugfix.rst \ No newline at end of file diff --git a/aiohttp/resolver.py b/aiohttp/resolver.py index 385ae21abf..c01a46fbb0 100644 --- a/aiohttp/resolver.py +++ b/aiohttp/resolver.py @@ -161,7 +161,7 @@ async def _resolve_with_query( resp = await self._resolver.query(host, qtype) except aiodns.error.DNSError as exc: msg = exc.args[1] if len(exc.args) >= 1 else "DNS lookup failed" - raise OSError(msg) from exc + raise OSError(None, msg) from exc hosts = [] for rr in resp: @@ -177,7 +177,7 @@ async def _resolve_with_query( ) if not hosts: - raise OSError("DNS lookup failed") + raise OSError(None, "DNS lookup failed") return hosts diff --git a/tests/test_resolver.py b/tests/test_resolver.py index 6322bcfca6..f8fba501ad 100644 --- a/tests/test_resolver.py +++ b/tests/test_resolver.py @@ -339,6 +339,36 @@ async def test_async_resolver_query_ipv6_positive_lookup(loop) -> None: mock().query.assert_called_with("www.python.org", "AAAA") +@pytest.mark.skipif(not getaddrinfo, reason="aiodns >=3.2.0 required") +async def test_async_resolver_query_fallback_error_messages_passed( + loop: asyncio.AbstractEventLoop, +) -> None: + """Ensure error messages are passed through from aiodns with query fallback.""" + with patch("aiodns.DNSResolver", autospec=True, spec_set=True) as mock: + del mock().gethostbyname + mock().query.side_effect = aiodns.error.DNSError(1, "Test error message") + resolver = AsyncResolver() + with pytest.raises(OSError, match="Test error message") as excinfo: + await resolver.resolve("x.org") + + assert excinfo.value.strerror == "Test error message" + + +@pytest.mark.skipif(not getaddrinfo, reason="aiodns >=3.2.0 required") +async def test_async_resolver_query_fallback_error_messages_passed_no_hosts( + loop: asyncio.AbstractEventLoop, +) -> None: + """Ensure error messages are passed through from aiodns with query fallback.""" + with patch("aiodns.DNSResolver", autospec=True, spec_set=True) as mock: + del mock().gethostbyname + mock().query.return_value = fake_query_result([]) + resolver = AsyncResolver() + with pytest.raises(OSError, match="DNS lookup failed") as excinfo: + await resolver.resolve("x.org") + + assert excinfo.value.strerror == "DNS lookup failed" + + @pytest.mark.skipif(not getaddrinfo, reason="aiodns >=3.2.0 required") async def test_async_resolver_error_messages_passed( loop: asyncio.AbstractEventLoop,