Raise in EntityComponent.async_prepare_reload on configuration error
This commit is contained in:
parent
07ceafed62
commit
fca50bfbf8
17 changed files with 49 additions and 43 deletions
|
@ -333,8 +333,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Remove all automations and load new ones from config."""
|
||||
await async_get_blueprints(hass).async_reset_cache()
|
||||
if (conf := await component.async_prepare_reload(skip_reset=True)) is None:
|
||||
return
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if automation_id := service_call.data.get(CONF_ID):
|
||||
await _async_process_single_config(hass, conf, component, automation_id)
|
||||
else:
|
||||
|
|
|
@ -194,8 +194,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
- Remove group.group entities not created by service calls and set them up again
|
||||
- Reload xxx.group platforms
|
||||
"""
|
||||
if (conf := await component.async_prepare_reload(skip_reset=True)) is None:
|
||||
return
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
|
||||
# Simplified + modified version of EntityPlatform.async_reset:
|
||||
# - group.group never retries setup
|
||||
|
|
|
@ -121,8 +121,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Remove all input booleans and load new ones from config."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
return
|
||||
await yaml_collection.async_load(
|
||||
[
|
||||
{CONF_ID: id_, **(conf or {})}
|
||||
|
|
|
@ -106,8 +106,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Remove all input buttons and load new ones from config."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
return
|
||||
await yaml_collection.async_load(
|
||||
[
|
||||
{CONF_ID: id_, **(conf or {})}
|
||||
|
|
|
@ -159,8 +159,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Reload yaml entities."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
conf = {DOMAIN: {}}
|
||||
await yaml_collection.async_load(
|
||||
[{CONF_ID: id_, **cfg} for id_, cfg in conf.get(DOMAIN, {}).items()]
|
||||
)
|
||||
|
|
|
@ -137,8 +137,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Reload yaml entities."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
conf = {DOMAIN: {}}
|
||||
await yaml_collection.async_load(
|
||||
[{CONF_ID: id_, **conf} for id_, conf in conf.get(DOMAIN, {}).items()]
|
||||
)
|
||||
|
|
|
@ -167,8 +167,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Reload yaml entities."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
conf = {DOMAIN: {}}
|
||||
await yaml_collection.async_load(
|
||||
[{CONF_ID: id_, **cfg} for id_, cfg in conf.get(DOMAIN, {}).items()]
|
||||
)
|
||||
|
|
|
@ -137,8 +137,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Reload yaml entities."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
conf = {DOMAIN: {}}
|
||||
await yaml_collection.async_load(
|
||||
[{CONF_ID: id_, **(cfg or {})} for id_, cfg in conf.get(DOMAIN, {}).items()]
|
||||
)
|
||||
|
|
|
@ -403,8 +403,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def async_reload_yaml(call: ServiceCall) -> None:
|
||||
"""Reload YAML."""
|
||||
conf = await entity_component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
return
|
||||
await yaml_collection.async_load(
|
||||
await filter_yaml_data(hass, conf.get(DOMAIN, []))
|
||||
)
|
||||
|
|
|
@ -187,8 +187,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Reload yaml entities."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
conf = {DOMAIN: {}}
|
||||
await yaml_collection.async_load(
|
||||
[{CONF_ID: id_, **cfg} for id_, cfg in conf.get(DOMAIN, {}).items()]
|
||||
)
|
||||
|
|
|
@ -229,8 +229,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service(service: ServiceCall) -> None:
|
||||
"""Call a service to reload scripts."""
|
||||
await async_get_blueprints(hass).async_reset_cache()
|
||||
if (conf := await component.async_prepare_reload(skip_reset=True)) is None:
|
||||
return
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
await _async_process_config(hass, conf, component)
|
||||
|
||||
async def turn_on_service(service: ServiceCall) -> None:
|
||||
|
|
|
@ -141,8 +141,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Reload yaml entities."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
conf = {DOMAIN: {}}
|
||||
await yaml_collection.async_load(
|
||||
[{CONF_ID: id_, **cfg} for id_, cfg in conf.get(DOMAIN, {}).items()]
|
||||
)
|
||||
|
|
|
@ -265,8 +265,6 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
|||
async def reload_service_handler(service_call: ServiceCall) -> None:
|
||||
"""Remove all zones and load new ones from config."""
|
||||
conf = await component.async_prepare_reload(skip_reset=True)
|
||||
if conf is None:
|
||||
return
|
||||
await yaml_collection.async_load(conf[DOMAIN])
|
||||
|
||||
service.async_register_admin_service(
|
||||
|
|
|
@ -16,7 +16,7 @@ from pathlib import Path
|
|||
import re
|
||||
import shutil
|
||||
from types import ModuleType
|
||||
from typing import TYPE_CHECKING, Any
|
||||
from typing import TYPE_CHECKING, Any, Literal, overload
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from awesomeversion import AwesomeVersion
|
||||
|
@ -1208,6 +1208,39 @@ def _get_log_message_and_stack_print_pref(
|
|||
return (log_message, show_stack_trace, placeholders)
|
||||
|
||||
|
||||
# The complicated overloads are due to a limitation in mypy, details in
|
||||
# https://github.com/python/mypy/issues/7333
|
||||
@overload
|
||||
@callback
|
||||
async def async_process_component_and_handle_errors(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType,
|
||||
integration: Integration,
|
||||
) -> ConfigType | None: ...
|
||||
|
||||
|
||||
@overload
|
||||
@callback
|
||||
async def async_process_component_and_handle_errors(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType,
|
||||
integration: Integration,
|
||||
*,
|
||||
raise_on_failure: Literal[True],
|
||||
) -> ConfigType: ...
|
||||
|
||||
|
||||
@overload
|
||||
@callback
|
||||
async def async_process_component_and_handle_errors(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType,
|
||||
integration: Integration,
|
||||
*,
|
||||
raise_on_failure: bool,
|
||||
) -> ConfigType | None: ...
|
||||
|
||||
|
||||
async def async_process_component_and_handle_errors(
|
||||
hass: HomeAssistant,
|
||||
config: ConfigType,
|
||||
|
@ -1226,7 +1259,7 @@ async def async_process_component_and_handle_errors(
|
|||
hass, config, integration
|
||||
)
|
||||
async_handle_component_errors(
|
||||
hass, integration_config_info, integration, raise_on_failure
|
||||
hass, integration_config_info, integration, raise_on_failure=raise_on_failure
|
||||
)
|
||||
return async_drop_config_annotations(integration_config_info, integration)
|
||||
|
||||
|
|
|
@ -348,28 +348,19 @@ class EntityComponent(Generic[_EntityT]):
|
|||
if found:
|
||||
await found.async_remove_entity(entity_id)
|
||||
|
||||
async def async_prepare_reload(
|
||||
self, *, skip_reset: bool = False
|
||||
) -> ConfigType | None:
|
||||
async def async_prepare_reload(self, *, skip_reset: bool = False) -> ConfigType:
|
||||
"""Prepare reloading this entity component.
|
||||
|
||||
This method must be run in the event loop.
|
||||
"""
|
||||
try:
|
||||
conf = await conf_util.async_hass_config_yaml(self.hass)
|
||||
except HomeAssistantError as err:
|
||||
self.logger.error(err)
|
||||
return None
|
||||
|
||||
integration = await async_get_integration(self.hass, self.domain)
|
||||
|
||||
processed_conf = await conf_util.async_process_component_and_handle_errors(
|
||||
self.hass, conf, integration
|
||||
self.hass, conf, integration, raise_on_failure=True
|
||||
)
|
||||
|
||||
if processed_conf is None:
|
||||
return None
|
||||
|
||||
if not skip_reset:
|
||||
await self._async_reset()
|
||||
|
||||
|
|
|
@ -136,6 +136,8 @@ async def _async_reconfig_platform(
|
|||
await asyncio.gather(*tasks)
|
||||
|
||||
|
||||
# The complicated overloads are due to a limitation in mypy, details in
|
||||
# https://github.com/python/mypy/issues/7333
|
||||
@overload
|
||||
async def async_integration_yaml_config(
|
||||
hass: HomeAssistant, integration_name: str
|
||||
|
|
|
@ -704,9 +704,12 @@ async def test_reload_config_handles_load_fails(
|
|||
assert len(calls) == 1
|
||||
assert calls[0].data.get("event") == "test_event"
|
||||
|
||||
with patch(
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.config.load_yaml_config_file",
|
||||
side_effect=HomeAssistantError("bla"),
|
||||
),
|
||||
pytest.raises(HomeAssistantError),
|
||||
):
|
||||
await hass.services.async_call(automation.DOMAIN, SERVICE_RELOAD, blocking=True)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue