From dc1d3f727b25c49f93bd26344af891c504a560b2 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Thu, 28 Sep 2023 02:59:19 +0200 Subject: [PATCH] Fix handling reload with invalid mqtt config (#101015) Fix handling reload whith invalid mqtt config --- homeassistant/components/mqtt/__init__.py | 13 +++++-- tests/components/mqtt/test_init.py | 41 +++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/mqtt/__init__.py b/homeassistant/components/mqtt/__init__.py index 5b5c39e6831..7caeb2b51f7 100644 --- a/homeassistant/components/mqtt/__init__.py +++ b/homeassistant/components/mqtt/__init__.py @@ -24,7 +24,7 @@ from homeassistant.const import ( SERVICE_RELOAD, ) from homeassistant.core import HassJob, HomeAssistant, ServiceCall, callback -from homeassistant.exceptions import TemplateError, Unauthorized +from homeassistant.exceptions import HomeAssistantError, TemplateError, Unauthorized from homeassistant.helpers import config_validation as cv, event as ev, template from homeassistant.helpers.device_registry import DeviceEntry from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -364,8 +364,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def _reload_config(call: ServiceCall) -> None: """Reload the platforms.""" - # Fetch updated manual configured items and validate - config_yaml = await async_integration_yaml_config(hass, DOMAIN) or {} + # 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" + ) mqtt_data.config = config_yaml.get(DOMAIN, {}) # Reload the modern yaml platforms diff --git a/tests/components/mqtt/test_init.py b/tests/components/mqtt/test_init.py index e3a12a2c24e..48d949ae927 100644 --- a/tests/components/mqtt/test_init.py +++ b/tests/components/mqtt/test_init.py @@ -3898,3 +3898,44 @@ async def test_reload_config_entry( assert state.state == "manual2_update_after_reload" assert (state := hass.states.get("sensor.test_manual3")) is not None assert state.state is STATE_UNAVAILABLE + + +@pytest.mark.parametrize( + "hass_config", + [ + { + "mqtt": [ + { + "sensor": { + "name": "test", + "state_topic": "test-topic", + } + }, + ] + } + ], +) +async def test_reload_with_invalid_config( + hass: HomeAssistant, + mqtt_mock_entry: MqttMockHAClientGenerator, +) -> None: + """Test reloading yaml config fails.""" + await mqtt_mock_entry() + assert hass.states.get("sensor.test") is not None + + # Reload with an invalid config and assert again + invalid_config = {"mqtt": "some_invalid_config"} + with patch( + "homeassistant.config.load_yaml_config_file", return_value=invalid_config + ): + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + "mqtt", + SERVICE_RELOAD, + {}, + blocking=True, + ) + await hass.async_block_till_done() + + # Test nothing changed as loading the config failed + assert hass.states.get("sensor.test") is not None