-
-
Notifications
You must be signed in to change notification settings - Fork 37.1k
Avoid crashing due to unexpected entity category #71346
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we should just ignore every unknown value.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Breaking startup of home assistant due to a single errounous value here is not a good ide.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An alternative would be to ignore the complete entity with bad data.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There are thousands of ways custom integrations could break the registries 🤷 Have we pinpointed the root cause/code/integration?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nope, we have two reported issues that i know of so far. |
||
| 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"], | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should also test the logger message |
||
| }, | ||
| { | ||
| "entity_id": "test.disabled_user", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not define that as inline function, let's place that as standalone function into that file