diff --git a/homeassistant/components/fritz/coordinator.py b/homeassistant/components/fritz/coordinator.py index 9e7e1d811be..571214d1d85 100644 --- a/homeassistant/components/fritz/coordinator.py +++ b/homeassistant/components/fritz/coordinator.py @@ -8,6 +8,7 @@ from functools import partial import logging import re from typing import Any, TypedDict, cast +from xml.etree.ElementTree import ParseError from fritzconnection import FritzConnection from fritzconnection.core.exceptions import FritzActionError @@ -24,7 +25,7 @@ from homeassistant.components.device_tracker import ( ) from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from homeassistant.exceptions import HomeAssistantError +from homeassistant.exceptions import ConfigEntryNotReady, HomeAssistantError from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC from homeassistant.helpers.dispatcher import async_dispatcher_send @@ -226,7 +227,13 @@ class FritzBoxTools(DataUpdateCoordinator[UpdateCoordinatorDataType]): self.fritz_guest_wifi = FritzGuestWLAN(fc=self.connection) self.fritz_status = FritzStatus(fc=self.connection) self.fritz_call = FritzCall(fc=self.connection) - info = self.fritz_status.get_device_info() + try: + info = self.fritz_status.get_device_info() + except ParseError as ex: + raise ConfigEntryNotReady( + translation_domain=DOMAIN, + translation_key="error_parse_device_info", + ) from ex _LOGGER.debug( "gathered device info of %s %s", diff --git a/homeassistant/components/fritz/strings.json b/homeassistant/components/fritz/strings.json index 67326ae4ea2..0ff85b8d5c8 100644 --- a/homeassistant/components/fritz/strings.json +++ b/homeassistant/components/fritz/strings.json @@ -185,6 +185,9 @@ "config_entry_not_found": { "message": "Failed to perform action \"{service}\". Config entry for target not found" }, + "error_parse_device_info": { + "message": "Error parsing device info. Please check the system event log of your FRITZ!Box for malformed data and clear the event list." + }, "error_refresh_hosts_info": { "message": "Error refreshing hosts info" }, diff --git a/tests/components/fritz/test_init.py b/tests/components/fritz/test_init.py index 024160dad68..9d7a23be096 100644 --- a/tests/components/fritz/test_init.py +++ b/tests/components/fritz/test_init.py @@ -2,6 +2,7 @@ import re from unittest.mock import patch +from xml.etree.ElementTree import ParseError from freezegun.api import FrozenDateTimeFactory import pytest @@ -116,6 +117,25 @@ async def test_setup_fail(hass: HomeAssistant, error) -> None: assert entry.state is ConfigEntryState.SETUP_RETRY +async def test_setup_fail_parse_error(hass: HomeAssistant, fc_class_mock) -> None: + """Test setup failure due to parse error while fetching device data.""" + + entry = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA) + entry.add_to_hass(hass) + + with ( + patch( + "homeassistant.components.fritz.coordinator.FritzStatus.get_device_info" + ) as fs_mock, + ): + fs_mock.side_effect = ParseError("boom") + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert entry.state is ConfigEntryState.SETUP_RETRY + assert entry.error_reason_translation_key == "error_parse_device_info" + + async def test_upnp_missing( hass: HomeAssistant, caplog: pytest.LogCaptureFixture,