From ff247fe8ecf169ae50416a0d9c9bd0d09b15782b Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Thu, 5 May 2022 15:45:15 +0200 Subject: [PATCH] Avoid crashing due to unexpected entity category --- homeassistant/helpers/entity_registry.py | 30 ++++++++++++++++++------ tests/helpers/test_entity_registry.py | 1 + 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/homeassistant/helpers/entity_registry.py b/homeassistant/helpers/entity_registry.py index b4dd0820d8cda9..7f88994432500c 100644 --- a/homeassistant/helpers/entity_registry.py +++ b/homeassistant/helpers/entity_registry.py @@ -12,7 +12,7 @@ from collections import UserDict from collections.abc import Callable, Iterable, Mapping import logging -from typing import TYPE_CHECKING, Any, cast +from typing import TYPE_CHECKING, Any, TypeVar, cast import attr import voluptuous as vol @@ -52,6 +52,9 @@ from .entity import EntityCategory +_StrEnumT = TypeVar("_StrEnumT", bound="StrEnum") + + PATH_REGISTRY = "entity_registry.yaml" DATA_REGISTRY = "entity_registry" EVENT_ENTITY_REGISTRY_UPDATED = "entity_registry_updated" @@ -703,6 +706,19 @@ async def async_load(self) -> None: from .entity import EntityCategory # pylint: disable=import-outside-toplevel + def parse_enum( + cls: type[_StrEnumT], value: str | None, default: _StrEnumT | None + ) -> _StrEnumT | None: + """Parse enum and ignore invalid values.""" + + if not value: + return None + try: + return cls(value) + except ValueError: + _LOGGER.warning("Ignoring unexpected value %s for enum %s", value, cls) + return default + if data is not None: for entity in data["entities"]: # Some old installations can have some bad entities. @@ -717,12 +733,12 @@ async def async_load(self) -> None: config_entry_id=entity["config_entry_id"], device_class=entity["device_class"], device_id=entity["device_id"], - disabled_by=RegistryEntryDisabler(entity["disabled_by"]) - if entity["disabled_by"] - else None, - entity_category=EntityCategory(entity["entity_category"]) - if entity["entity_category"] - else None, + disabled_by=parse_enum( + RegistryEntryDisabler, entity["disabled_by"], None + ), + entity_category=parse_enum( + EntityCategory, entity["entity_category"], None + ), entity_id=entity["entity_id"], hidden_by=entity["hidden_by"], icon=entity["icon"], diff --git a/tests/helpers/test_entity_registry.py b/tests/helpers/test_entity_registry.py index 41ac7412d9c36f..519f54444dde24 100644 --- a/tests/helpers/test_entity_registry.py +++ b/tests/helpers/test_entity_registry.py @@ -278,6 +278,7 @@ async def test_loading_extra_values(hass, hass_storage): "entity_id": "test.no_name", "platform": "super_platform", "unique_id": "without-name", + "disabled_by": "ignored-invalid-disabled-by", }, { "entity_id": "test.disabled_user",