Raise and suppress stack trace when reloading yaml fails (#102410)

* Allow async_integration_yaml_config to raise

* Docstr - split check

* Implement as wrapper, return dataclass

* Fix setup error handling

* Fix reload test mock

* Move log_messages to error handler

* Remove unreachable code

* Remove config test helper

* Refactor and ensure notifications during setup

* Remove redundat error, adjust tests notifications

* Fix patch

* Apply suggestions from code review

Co-authored-by: Erik Montnemery <erik@montnemery.com>

* Follow up comments

* Add call_back decorator

* Split long lines

* Update exception abbreviations

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Jan Bouwhuis 2023-11-24 17:34:45 +01:00 committed by GitHub
parent 852fb58ca8
commit af71c2bb45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 954 additions and 195 deletions

View file

@ -11,14 +11,13 @@ from types import ModuleType
from typing import Any
from . import config as conf_util, core, loader, requirements
from .config import async_notify_setup_error
from .const import (
EVENT_COMPONENT_LOADED,
EVENT_HOMEASSISTANT_START,
PLATFORM_FORMAT,
Platform,
)
from .core import CALLBACK_TYPE, DOMAIN as HOMEASSISTANT_DOMAIN
from .core import CALLBACK_TYPE, DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
from .exceptions import DependencyError, HomeAssistantError
from .helpers.issue_registry import IssueSeverity, async_create_issue
from .helpers.typing import ConfigType
@ -56,10 +55,47 @@ DATA_SETUP_TIME = "setup_time"
DATA_DEPS_REQS = "deps_reqs_processed"
DATA_PERSISTENT_ERRORS = "bootstrap_persistent_errors"
NOTIFY_FOR_TRANSLATION_KEYS = [
"config_validation_err",
"platform_config_validation_err",
]
SLOW_SETUP_WARNING = 10
SLOW_SETUP_MAX_WAIT = 300
@callback
def async_notify_setup_error(
hass: HomeAssistant, component: str, display_link: str | None = None
) -> None:
"""Print a persistent notification.
This method must be run in the event loop.
"""
# pylint: disable-next=import-outside-toplevel
from .components import persistent_notification
if (errors := hass.data.get(DATA_PERSISTENT_ERRORS)) is None:
errors = hass.data[DATA_PERSISTENT_ERRORS] = {}
errors[component] = errors.get(component) or display_link
message = "The following integrations and platforms could not be set up:\n\n"
for name, link in errors.items():
show_logs = f"[Show logs](/config/logs?filter={name})"
part = f"[{name}]({link})" if link else name
message += f" - {part} ({show_logs})\n"
message += "\nPlease check your config and [logs](/config/logs)."
persistent_notification.async_create(
hass, message, "Invalid config", "invalid_config"
)
@core.callback
def async_set_domains_to_be_loaded(hass: core.HomeAssistant, domains: set[str]) -> None:
"""Set domains that are going to be loaded from the config.
@ -217,10 +253,18 @@ async def _async_setup_component(
log_error(f"Unable to import component: {err}", err)
return False
processed_config = await conf_util.async_process_component_config(
integration_config_info = await conf_util.async_process_component_config(
hass, config, integration
)
processed_config = conf_util.async_handle_component_errors(
hass, integration_config_info, integration
)
for platform_exception in integration_config_info.exception_info_list:
if platform_exception.translation_key not in NOTIFY_FOR_TRANSLATION_KEYS:
continue
async_notify_setup_error(
hass, platform_exception.platform_name, platform_exception.integration_link
)
if processed_config is None:
log_error("Invalid config.")
return False