From fdc5208d18b900c429b149aa0a9b1c9ec09bd874 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 22 Jul 2020 20:21:57 -1000 Subject: [PATCH] Prevent the zeroconf service browser from terminating when a device without any addresses is discovered. (#38094) --- homeassistant/components/zeroconf/__init__.py | 8 +++++++ tests/components/zeroconf/test_init.py | 23 +++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/homeassistant/components/zeroconf/__init__.py b/homeassistant/components/zeroconf/__init__.py index 06832386621..4da6fd5ab80 100644 --- a/homeassistant/components/zeroconf/__init__.py +++ b/homeassistant/components/zeroconf/__init__.py @@ -210,6 +210,11 @@ def setup(hass, config): return info = info_from_service(service_info) + if not info: + # Prevent the browser thread from collapsing + _LOGGER.debug("Failed to get addresses for device %s", name) + return + _LOGGER.debug("Discovered new device %s %s", name, info) # If we can handle it as a HomeKit discovery, we do that here. @@ -317,6 +322,9 @@ def info_from_service(service): except UnicodeDecodeError: pass + if not service.addresses: + return None + address = service.addresses[0] info = { diff --git a/tests/components/zeroconf/test_init.py b/tests/components/zeroconf/test_init.py index 0c32e60ecca..e8315b5dc75 100644 --- a/tests/components/zeroconf/test_init.py +++ b/tests/components/zeroconf/test_init.py @@ -49,6 +49,20 @@ def get_service_info_mock(service_type, name): ) +def get_service_info_mock_without_an_address(service_type, name): + """Return service info for get_service_info without any addresses.""" + return ServiceInfo( + service_type, + name, + addresses=[], + port=80, + weight=0, + priority=0, + server="name.local.", + properties=PROPERTIES, + ) + + def get_homekit_info_mock(model, pairing_status): """Return homekit info for get_service_info for an homekit device.""" @@ -308,6 +322,15 @@ async def test_info_from_service_non_utf8(hass): assert raw_info["non-utf8-value"] is NON_UTF8_VALUE +async def test_info_from_service_with_addresses(hass): + """Test info_from_service does not throw when there are no addresses.""" + service_type = "_test._tcp.local." + info = zeroconf.info_from_service( + get_service_info_mock_without_an_address(service_type, f"test.{service_type}") + ) + assert info is None + + async def test_get_instance(hass, mock_zeroconf): """Test we get an instance.""" assert await hass.components.zeroconf.async_get_instance() is mock_zeroconf