mirror of
https://github.com/home-assistant/core.git
synced 2025-07-13 16:27:08 +00:00
Catch unexpected exceptions when validating config (#31795)
This commit is contained in:
parent
6211a2bb98
commit
fbbb29a6ec
@ -697,6 +697,9 @@ async def async_process_component_config(
|
||||
except (vol.Invalid, HomeAssistantError) as ex:
|
||||
async_log_exception(ex, domain, config, hass, integration.documentation)
|
||||
return None
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unknown error calling %s config validator", domain)
|
||||
return None
|
||||
|
||||
# No custom config validator, proceed with schema validation
|
||||
if hasattr(component, "CONFIG_SCHEMA"):
|
||||
@ -705,6 +708,9 @@ async def async_process_component_config(
|
||||
except vol.Invalid as ex:
|
||||
async_log_exception(ex, domain, config, hass, integration.documentation)
|
||||
return None
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unknown error calling %s CONFIG_SCHEMA", domain)
|
||||
return None
|
||||
|
||||
component_platform_schema = getattr(
|
||||
component, "PLATFORM_SCHEMA_BASE", getattr(component, "PLATFORM_SCHEMA", None)
|
||||
@ -721,6 +727,13 @@ async def async_process_component_config(
|
||||
except vol.Invalid as ex:
|
||||
async_log_exception(ex, domain, p_config, hass, integration.documentation)
|
||||
continue
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception(
|
||||
"Unknown error validating %s platform config with %s component platform schema",
|
||||
p_name,
|
||||
domain,
|
||||
)
|
||||
continue
|
||||
|
||||
# Not all platform components follow same pattern for platforms
|
||||
# So if p_name is None we are not going to validate platform
|
||||
@ -756,6 +769,13 @@ async def async_process_component_config(
|
||||
p_integration.documentation,
|
||||
)
|
||||
continue
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception(
|
||||
"Unknown error validating config for %s platform for %s component with PLATFORM_SCHEMA",
|
||||
p_name,
|
||||
domain,
|
||||
)
|
||||
continue
|
||||
|
||||
platforms.append(p_validated)
|
||||
|
||||
|
@ -4,9 +4,11 @@ import asyncio
|
||||
from collections import OrderedDict
|
||||
import copy
|
||||
import os
|
||||
import unittest.mock as mock
|
||||
from unittest import mock
|
||||
from unittest.mock import Mock
|
||||
|
||||
import asynctest
|
||||
from asynctest import CoroutineMock, patch
|
||||
import pytest
|
||||
from voluptuous import Invalid, MultipleInvalid
|
||||
import yaml
|
||||
@ -893,3 +895,97 @@ async def test_merge_split_component_definition(hass):
|
||||
assert len(config["light one"]) == 1
|
||||
assert len(config["light two"]) == 1
|
||||
assert len(config["light three"]) == 1
|
||||
|
||||
|
||||
async def test_component_config_exceptions(hass, caplog):
|
||||
"""Test unexpected exceptions validating component config."""
|
||||
# Config validator
|
||||
assert (
|
||||
await config_util.async_process_component_config(
|
||||
hass,
|
||||
{},
|
||||
integration=Mock(
|
||||
domain="test_domain",
|
||||
get_platform=Mock(
|
||||
return_value=Mock(
|
||||
async_validate_config=CoroutineMock(
|
||||
side_effect=ValueError("broken")
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
is None
|
||||
)
|
||||
assert "ValueError: broken" in caplog.text
|
||||
assert "Unknown error calling test_domain config validator" in caplog.text
|
||||
|
||||
# component.CONFIG_SCHEMA
|
||||
caplog.clear()
|
||||
assert (
|
||||
await config_util.async_process_component_config(
|
||||
hass,
|
||||
{},
|
||||
integration=Mock(
|
||||
domain="test_domain",
|
||||
get_platform=Mock(return_value=None),
|
||||
get_component=Mock(
|
||||
return_value=Mock(
|
||||
CONFIG_SCHEMA=Mock(side_effect=ValueError("broken"))
|
||||
)
|
||||
),
|
||||
),
|
||||
)
|
||||
is None
|
||||
)
|
||||
assert "ValueError: broken" in caplog.text
|
||||
assert "Unknown error calling test_domain CONFIG_SCHEMA" in caplog.text
|
||||
|
||||
# component.PLATFORM_SCHEMA
|
||||
caplog.clear()
|
||||
assert await config_util.async_process_component_config(
|
||||
hass,
|
||||
{"test_domain": {"platform": "test_platform"}},
|
||||
integration=Mock(
|
||||
domain="test_domain",
|
||||
get_platform=Mock(return_value=None),
|
||||
get_component=Mock(
|
||||
return_value=Mock(
|
||||
spec=["PLATFORM_SCHEMA_BASE"],
|
||||
PLATFORM_SCHEMA_BASE=Mock(side_effect=ValueError("broken")),
|
||||
)
|
||||
),
|
||||
),
|
||||
) == {"test_domain": []}
|
||||
assert "ValueError: broken" in caplog.text
|
||||
assert (
|
||||
"Unknown error validating test_platform platform config with test_domain component platform schema"
|
||||
in caplog.text
|
||||
)
|
||||
|
||||
# platform.PLATFORM_SCHEMA
|
||||
caplog.clear()
|
||||
with patch(
|
||||
"homeassistant.config.async_get_integration_with_requirements",
|
||||
return_value=Mock( # integration that owns platform
|
||||
get_platform=Mock(
|
||||
return_value=Mock( # platform
|
||||
PLATFORM_SCHEMA=Mock(side_effect=ValueError("broken"))
|
||||
)
|
||||
)
|
||||
),
|
||||
):
|
||||
assert await config_util.async_process_component_config(
|
||||
hass,
|
||||
{"test_domain": {"platform": "test_platform"}},
|
||||
integration=Mock(
|
||||
domain="test_domain",
|
||||
get_platform=Mock(return_value=None),
|
||||
get_component=Mock(return_value=Mock(spec=["PLATFORM_SCHEMA_BASE"])),
|
||||
),
|
||||
) == {"test_domain": []}
|
||||
assert "ValueError: broken" in caplog.text
|
||||
assert (
|
||||
"Unknown error validating config for test_platform platform for test_domain component with PLATFORM_SCHEMA"
|
||||
in caplog.text
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user