Skip to content
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

Raise and suppress stack trace when reloading yaml fails #102410

Merged
merged 19 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion homeassistant/components/homeassistant/scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ async def reload_config(call: ServiceCall) -> None:

integration = await async_get_integration(hass, SCENE_DOMAIN)

conf = await conf_util.async_process_component_config(hass, config, integration)
conf = await conf_util.async_process_component_and_handle_errors(
hass, config, integration
)

if not (conf and platform):
return
Expand Down
33 changes: 33 additions & 0 deletions homeassistant/components/homeassistant/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,39 @@
}
},
"exceptions": {
"component_import_err": {
"message": "Unable to import {domain}: {error}"
},
"config_platform_import_err": {
"message": "Error importing config platform {domain}: {error}"
},
"config_validation_err": {
"message": "Invalid config for integration {domain} at {config_file}, line {line}: {error}. Check the logs for more information."
},
"config_validator_unknown_err": {
"message": "Unknown error calling {domain} config validator. Check the logs for more information."
},
"config_schema_unknown_err": {
"message": "Unknown error calling {domain} CONFIG_SCHEMA. Check the logs for more information."
},
"integration_config_error": {
"message": "Failed to process component config for integration {domain} due to multiple ({errors}) errors. Check the logs for more information."
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
},
"platform_component_load_err": {
"message": "Platform error: {domain} - {error}. Check the logs for more information."
},
"platform_component_load_exc": {
"message": "Platform error: {domain} - {error}. Check the logs for more information."
},
"platform_config_validation_err": {
"message": "Invalid config for integration platform {domain}.{p_name} at file {config_file}, line {line}: {error}. Check the logs for more information."
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
},
"platform_schema_validator_err": {
"message": "Unknown error validating config for {p_name} platform for {domain} component with PLATFORM_SCHEMA"
jbouwh marked this conversation as resolved.
Show resolved Hide resolved
},
"platform_validator_unknown_err": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between this and the above error string? The text is too similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

platform_validator_unknown_err indicates an unexpected error happened when validation a specific platform schema. I did not change the actual error messages that are in dev right now, as it breaks other tests.

core/homeassistant/config.py

Lines 1228 to 1247 in 4bf2b38

# Validate component specific platform schema
platform_name = f"{domain}.{p_name}"
try:
p_validated = component_platform_schema(p_config)
except vol.Invalid as ex:
ex_info = ConfigExceptionInfo(
ex, "platform_config_validation_err", domain, p_config
)
config_exceptions.append(ex_info)
continue
except Exception as ex: # pylint: disable=broad-except
log_message = (
f"Unknown error validating {p_name} platform config with {domain} component"
" platform schema"
)
ex_info = ConfigExceptionInfo(
ex, "platform_validator_unknown_err", platform_name, config, log_message
)
config_exceptions.append(ex_info)
continue

platform_schema_validator_err indicates an unexpected error happened when trying to validate against a PLATFORM_SCHEMA.

core/homeassistant/config.py

Lines 1281 to 1309 in 4bf2b38

# Validate platform specific schema
if hasattr(platform, "PLATFORM_SCHEMA"):
try:
p_validated = platform.PLATFORM_SCHEMA(p_config)
except vol.Invalid as ex:
ex_info = ConfigExceptionInfo(
ex,
"platform_config_validation_err",
platform_name,
p_config,
integration_link=p_integration.documentation,
)
config_exceptions.append(ex_info)
continue
except Exception as ex: # pylint: disable=broad-except
log_message = (
f"Unknown error validating config for {p_name} platform "
f"for {domain} component with PLATFORM_SCHEMA"
)
ex_info = ConfigExceptionInfo(
ex,
"platform_schema_validator_err",
platform_name,
p_config,
log_message,
show_stack_trace=True,
)
config_exceptions.append(ex_info)
continue

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but why does the user care? I don't see any reason to have both platform_schema_validator_err and platform_validator_unknown_err. Please remove one of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed platform_validator_unknown_err

"message": "Unknown error validating {p_name} platform config with {domain} component platform schema."
},
"service_not_found": {
"message": "Service {domain}.{service} not found."
}
Expand Down
9 changes: 7 additions & 2 deletions homeassistant/components/lovelace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import voluptuous as vol

from homeassistant.components import frontend, websocket_api
from homeassistant.config import async_hass_config_yaml, async_process_component_config
from homeassistant.config import (
async_hass_config_yaml,
async_process_component_and_handle_errors,
)
from homeassistant.const import CONF_FILENAME, CONF_MODE, CONF_RESOURCES
from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import HomeAssistantError
Expand Down Expand Up @@ -85,7 +88,9 @@ async def reload_resources_service_handler(service_call: ServiceCall) -> None:

integration = await async_get_integration(hass, DOMAIN)

config = await async_process_component_config(hass, conf, integration)
config = await async_process_component_and_handle_errors(
hass, conf, integration
)

if config is None:
raise HomeAssistantError("Config validation failed")
Expand Down
20 changes: 12 additions & 8 deletions homeassistant/components/mqtt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
)
from homeassistant.core import HassJob, HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import (
HomeAssistantError,
ConfigValidationError,
ServiceValidationError,
TemplateError,
Unauthorized,
Expand Down Expand Up @@ -417,14 +417,18 @@ async def async_setup_reload_service() -> None:
async def _reload_config(call: ServiceCall) -> None:
"""Reload the platforms."""
# Fetch updated manually configured items and validate
if (
config_yaml := await async_integration_yaml_config(hass, DOMAIN)
) is None:
# Raise in case we have an invalid configuration
raise HomeAssistantError(
"Error reloading manually configured MQTT items, "
"check your configuration.yaml"
try:
config_yaml = await async_integration_yaml_config(
hass, DOMAIN, raise_on_failure=True
)
except ConfigValidationError as ex:
raise ServiceValidationError(
str(ex),
translation_domain=ex.translation_domain,
translation_key=ex.translation_key,
translation_placeholders=ex.translation_placeholders,
) from ex

jbouwh marked this conversation as resolved.
Show resolved Hide resolved
# Check the schema before continuing reload
await async_check_config_schema(hass, config_yaml)

Expand Down
5 changes: 3 additions & 2 deletions homeassistant/components/template/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,9 @@ async def _reload_config(call: Event | ServiceCall) -> None:
_LOGGER.error(err)
return

conf = await conf_util.async_process_component_config(
hass, unprocessed_conf, await async_get_integration(hass, DOMAIN)
integration = await async_get_integration(hass, DOMAIN)
conf = await conf_util.async_process_component_and_handle_errors(
hass, unprocessed_conf, integration
)

if conf is None:
Expand Down
Loading
Loading