diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index 9694c299b23..2f2a8e93b1e 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -26,6 +26,7 @@ from homeassistant.const import ( EVENT_THEMES_UPDATED, ) from homeassistant.core import HomeAssistant, ServiceCall, callback +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, service from homeassistant.helpers.icon import async_get_icons from homeassistant.helpers.json import json_dumps_sorted @@ -543,6 +544,12 @@ async def _async_setup_themes( """Reload themes.""" config = await async_hass_config_yaml(hass) new_themes = config.get(DOMAIN, {}).get(CONF_THEMES, {}) + + try: + THEME_SCHEMA(new_themes) + except vol.Invalid as err: + raise HomeAssistantError(f"Failed to reload themes: {err}") from err + hass.data[DATA_THEMES] = new_themes if hass.data[DATA_DEFAULT_THEME] not in new_themes: hass.data[DATA_DEFAULT_THEME] = DEFAULT_THEME diff --git a/tests/components/frontend/test_init.py b/tests/components/frontend/test_init.py index f28742cdd0a..a6c35513dc3 100644 --- a/tests/components/frontend/test_init.py +++ b/tests/components/frontend/test_init.py @@ -26,6 +26,7 @@ from homeassistant.components.frontend import ( ) from homeassistant.components.websocket_api import TYPE_RESULT from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.loader import async_get_integration from homeassistant.setup import async_setup_component @@ -408,6 +409,35 @@ async def test_themes_reload_themes( assert msg["result"]["default_theme"] == "default" +@pytest.mark.usefixtures("frontend") +async def test_themes_reload_invalid( + hass: HomeAssistant, themes_ws_client: MockHAClientWebSocket +) -> None: + """Test frontend.reload_themes service with an invalid theme.""" + + with patch( + "homeassistant.components.frontend.async_hass_config_yaml", + return_value={DOMAIN: {CONF_THEMES: {"happy": {"primary-color": "pink"}}}}, + ): + await hass.services.async_call(DOMAIN, "reload_themes", blocking=True) + + with ( + patch( + "homeassistant.components.frontend.async_hass_config_yaml", + return_value={DOMAIN: {CONF_THEMES: {"sad": "blue"}}}, + ), + pytest.raises(HomeAssistantError, match="Failed to reload themes"), + ): + await hass.services.async_call(DOMAIN, "reload_themes", blocking=True) + + await themes_ws_client.send_json({"id": 5, "type": "frontend/get_themes"}) + + msg = await themes_ws_client.receive_json() + + assert msg["result"]["themes"] == {"happy": {"primary-color": "pink"}} + assert msg["result"]["default_theme"] == "default" + + async def test_missing_themes(ws_client: MockHAClientWebSocket) -> None: """Test that themes API works when themes are not defined.""" await ws_client.send_json({"id": 5, "type": "frontend/get_themes"})