diff --git a/homeassistant/components/alert/__init__.py b/homeassistant/components/alert/__init__.py index 9b3fb0f29c8..721ed0d0c21 100644 --- a/homeassistant/components/alert/__init__.py +++ b/homeassistant/components/alert/__init__.py @@ -26,6 +26,7 @@ from homeassistant.const import ( STATE_ON, ) from homeassistant.core import HassJob, HomeAssistant +from homeassistant.exceptions import ServiceNotFound import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_component import EntityComponent @@ -293,9 +294,15 @@ class Alert(Entity): LOGGER.debug(msg_payload) for target in self._notifiers: - await self.hass.services.async_call( - DOMAIN_NOTIFY, target, msg_payload, context=self._context - ) + try: + await self.hass.services.async_call( + DOMAIN_NOTIFY, target, msg_payload, context=self._context + ) + except ServiceNotFound: + LOGGER.error( + "Failed to call notify.%s, retrying at next notification interval", + target, + ) async def async_turn_on(self, **kwargs: Any) -> None: """Async Unacknowledge alert.""" diff --git a/tests/components/alert/test_init.py b/tests/components/alert/test_init.py index 550727a2a22..8dfbb437646 100644 --- a/tests/components/alert/test_init.py +++ b/tests/components/alert/test_init.py @@ -36,6 +36,7 @@ from tests.common import async_mock_service NAME = "alert_test" DONE_MESSAGE = "alert_gone" NOTIFIER = "test" +BAD_NOTIFIER = "bad_notifier" TEMPLATE = "{{ states.sensor.test.entity_id }}" TEST_ENTITY = "sensor.test" TITLE = "{{ states.sensor.test.entity_id }}" @@ -199,6 +200,26 @@ async def test_notification( assert len(mock_notifier) == 2 +async def test_bad_notifier( + hass: HomeAssistant, mock_notifier: list[ServiceCall] +) -> None: + """Test a broken notifier does not break the alert.""" + config = deepcopy(TEST_CONFIG) + config[DOMAIN][NAME][CONF_NOTIFIERS] = [BAD_NOTIFIER, NOTIFIER] + assert await async_setup_component(hass, DOMAIN, config) + assert len(mock_notifier) == 0 + + hass.states.async_set("sensor.test", STATE_ON) + await hass.async_block_till_done() + assert len(mock_notifier) == 1 + assert hass.states.get(ENTITY_ID).state == STATE_ON + + hass.states.async_set("sensor.test", STATE_OFF) + await hass.async_block_till_done() + assert len(mock_notifier) == 2 + assert hass.states.get(ENTITY_ID).state == STATE_IDLE + + async def test_no_notifiers( hass: HomeAssistant, mock_notifier: list[ServiceCall] ) -> None: