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 #9451/216e082 backport][3.10] Fix AsyncResolver swallowing the error message #9452

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/9451.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed error messages from :py:class:`~aiohttp.resolver.AsyncResolver` being swallowed -- by :user:`bdraco`.
4 changes: 2 additions & 2 deletions aiohttp/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ async def resolve(
)
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: List[ResolveResult] = []
for node in resp.nodes:
address: Union[Tuple[bytes, int], Tuple[bytes, int, int, int]] = node.addr
Expand Down Expand Up @@ -145,7 +145,7 @@ async def resolve(
)

if not hosts:
raise OSError("DNS lookup failed")
raise OSError(None, "DNS lookup failed")

return hosts

Expand Down
30 changes: 29 additions & 1 deletion tests/test_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,35 @@ async def test_async_resolver_query_ipv6_positive_lookup(loop) -> None:
mock().query.assert_called_with("www.python.org", "AAAA")


async def test_async_resolver_aiodns_not_present(loop, monkeypatch) -> None:
@pytest.mark.skipif(not getaddrinfo, reason="aiodns >=3.2.0 required")
async def test_async_resolver_error_messages_passed(
loop: asyncio.AbstractEventLoop,
) -> None:
"""Ensure error messages are passed through from aiodns."""
with patch("aiodns.DNSResolver", autospec=True, spec_set=True) as mock:
mock().getaddrinfo.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_error_messages_passed_no_hosts(
loop: asyncio.AbstractEventLoop,
) -> None:
"""Ensure error messages are passed through from aiodns."""
with patch("aiodns.DNSResolver", autospec=True, spec_set=True) as mock:
mock().getaddrinfo.return_value = fake_aiodns_getaddrinfo_ipv6_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"


async def test_async_resolver_aiodns_not_present(loop: Any, monkeypatch: Any) -> None:
monkeypatch.setattr("aiohttp.resolver.aiodns", None)
with pytest.raises(RuntimeError):
AsyncResolver(loop=loop)
Expand Down
Loading