diff --git a/homeassistant/components/dnsip/config_flow.py b/homeassistant/components/dnsip/config_flow.py index b2a4ff0338808..27dfcc6f89d43 100644 --- a/homeassistant/components/dnsip/config_flow.py +++ b/homeassistant/components/dnsip/config_flow.py @@ -1,11 +1,9 @@ """Adds config flow for dnsip integration.""" import asyncio -import contextlib from typing import Any, Literal import aiodns -from aiodns.error import DNSError import voluptuous as vol from homeassistant.config_entries import ( @@ -61,15 +59,16 @@ async def async_validate_hostname( async def async_check( hostname: str, resolver: str, qtype: Literal["A", "AAAA"], port: int = 53 - ) -> bool: - """Return if able to resolve hostname.""" - result: bool = False - with contextlib.suppress(DNSError): - _resolver = aiodns.DNSResolver( - nameservers=[resolver], udp_port=port, tcp_port=port - ) - result = bool(await _resolver.query(hostname, qtype)) + ) -> list: + """Return list of hostnames.""" + _resolver = aiodns.DNSResolver( + nameservers=[resolver], udp_port=port, tcp_port=port + ) + try: + result = await _resolver.query(hostname, qtype) + finally: + await _resolver.close() return result result: dict[str, bool] = {} @@ -78,11 +77,14 @@ async def async_check( async_check(hostname, resolver_ipv4, "A", port=port), async_check(hostname, resolver_ipv6, "AAAA", port=port_ipv6), async_check(hostname, resolver_ipv4, "AAAA", port=port), + return_exceptions=True, ) - result[CONF_IPV4] = tasks[0] - result[CONF_IPV6] = tasks[1] - result[CONF_IPV6_V4] = tasks[2] + result[CONF_IPV4] = bool(tasks[0]) if not isinstance(tasks[0], Exception) else False + result[CONF_IPV6] = bool(tasks[1]) if not isinstance(tasks[1], Exception) else False + result[CONF_IPV6_V4] = ( + bool(tasks[2]) if not isinstance(tasks[2], Exception) else False + ) return result diff --git a/homeassistant/components/dnsip/sensor.py b/homeassistant/components/dnsip/sensor.py index dd5a4f38aab37..6b9fbaed7fb56 100644 --- a/homeassistant/components/dnsip/sensor.py +++ b/homeassistant/components/dnsip/sensor.py @@ -7,7 +7,7 @@ from typing import Literal import aiodns -from aiodns.error import DNSError +from pycares import AresError from homeassistant.components.sensor import SensorEntity from homeassistant.config_entries import ConfigEntry @@ -114,18 +114,20 @@ def create_dns_resolver(self) -> None: async def async_update(self) -> None: """Get the current DNS IP address for hostname.""" - if self.resolver._closed: # noqa: SLF001 - self.create_dns_resolver() response = None try: async with asyncio.timeout(10): + if self.resolver._closed: # noqa: SLF001 + self.create_dns_resolver() response = await self.resolver.query(self.hostname, self.querytype) except TimeoutError as err: _LOGGER.debug("Timeout while resolving host: %s", err) - await self.resolver.close() - except DNSError as err: - _LOGGER.warning("Exception while resolving host: %s", err) - await self.resolver.close() + if self.resolver: + await self.resolver.close() + except (aiodns.error.DNSError, AresError, asyncio.CancelledError) as err: + _LOGGER.debug("Exception while resolving host: %s", err) + if self.resolver: + await self.resolver.close() if response: sorted_ips = sort_ips( diff --git a/tests/components/dnsip/test_config_flow.py b/tests/components/dnsip/test_config_flow.py index c74aac2d8412f..034faedff5b60 100644 --- a/tests/components/dnsip/test_config_flow.py +++ b/tests/components/dnsip/test_config_flow.py @@ -3,6 +3,7 @@ from unittest.mock import patch from aiodns.error import DNSError +from pycares import AresError import pytest from homeassistant import config_entries @@ -121,7 +122,14 @@ async def test_form_adv(hass: HomeAssistant) -> None: assert len(mock_setup_entry.mock_calls) == 1 -async def test_form_error(hass: HomeAssistant) -> None: +@pytest.mark.parametrize( + "error", + [ + (DNSError), + (AresError), + ], +) +async def test_form_error(hass: HomeAssistant, error: type[Exception]) -> None: """Test validate url fails.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} @@ -129,7 +137,7 @@ async def test_form_error(hass: HomeAssistant) -> None: with patch( "homeassistant.components.dnsip.config_flow.aiodns.DNSResolver", - side_effect=DNSError("Did not find"), + side_effect=error("Did not find"), ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"],