From 6003f3d135cfa8acebf390fae640bd7107a2f4ec Mon Sep 17 00:00:00 2001 From: Simone Chemelli Date: Mon, 26 May 2025 20:47:46 +0300 Subject: [PATCH] Add action exceptions to UptimeRobot integration (#143587) * Add action exceptions to UptimeRobot integration * fix tests and strings --- .../components/uptimerobot/quality_scale.yaml | 4 +- .../components/uptimerobot/strings.json | 5 ++ .../components/uptimerobot/switch.py | 18 ++++--- tests/components/uptimerobot/test_switch.py | 48 +++++++++++-------- 4 files changed, 47 insertions(+), 28 deletions(-) diff --git a/homeassistant/components/uptimerobot/quality_scale.yaml b/homeassistant/components/uptimerobot/quality_scale.yaml index 43076320b8f..1244d6a4c19 100644 --- a/homeassistant/components/uptimerobot/quality_scale.yaml +++ b/homeassistant/components/uptimerobot/quality_scale.yaml @@ -26,9 +26,7 @@ rules: unique-config-entry: done # Silver - action-exceptions: - status: todo - comment: we should not swallow the exception in switch.py + action-exceptions: done config-entry-unloading: done docs-configuration-parameters: done docs-installation-parameters: done diff --git a/homeassistant/components/uptimerobot/strings.json b/homeassistant/components/uptimerobot/strings.json index 6bcd1554b16..ffee6769c69 100644 --- a/homeassistant/components/uptimerobot/strings.json +++ b/homeassistant/components/uptimerobot/strings.json @@ -45,5 +45,10 @@ } } } + }, + "exceptions": { + "api_exception": { + "message": "Could not turn on/off monitoring: {error}" + } } } diff --git a/homeassistant/components/uptimerobot/switch.py b/homeassistant/components/uptimerobot/switch.py index 9b25570393a..5d80903ed02 100644 --- a/homeassistant/components/uptimerobot/switch.py +++ b/homeassistant/components/uptimerobot/switch.py @@ -12,9 +12,10 @@ from homeassistant.components.switch import ( SwitchEntityDescription, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback -from .const import API_ATTR_OK, LOGGER +from .const import API_ATTR_OK, DOMAIN from .coordinator import UptimeRobotConfigEntry from .entity import UptimeRobotEntity @@ -57,16 +58,21 @@ class UptimeRobotSwitch(UptimeRobotEntity, SwitchEntity): try: response = await self.api.async_edit_monitor(**kwargs) except UptimeRobotAuthenticationException: - LOGGER.debug("API authentication error, calling reauth") self.coordinator.config_entry.async_start_reauth(self.hass) return except UptimeRobotException as exception: - LOGGER.error("API exception: %s", exception) - return + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="api_exception", + translation_placeholders={"error": repr(exception)}, + ) from exception if response.status != API_ATTR_OK: - LOGGER.error("API exception: %s", response.error.message, exc_info=True) - return + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="api_exception", + translation_placeholders={"error": response.error.message}, + ) await self.coordinator.async_request_refresh() diff --git a/tests/components/uptimerobot/test_switch.py b/tests/components/uptimerobot/test_switch.py index 8c2cffe504a..48e9da05720 100644 --- a/tests/components/uptimerobot/test_switch.py +++ b/tests/components/uptimerobot/test_switch.py @@ -3,7 +3,7 @@ from unittest.mock import patch import pytest -from pyuptimerobot import UptimeRobotAuthenticationException +from pyuptimerobot import UptimeRobotAuthenticationException, UptimeRobotException from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN from homeassistant.const import ( @@ -14,6 +14,7 @@ from homeassistant.const import ( STATE_ON, ) from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError from .common import ( MOCK_UPTIMEROBOT_CONFIG_ENTRY_DATA, @@ -128,18 +129,20 @@ async def test_authentication_error( assert config_entry_reauth.assert_called -async def test_refresh_data( - hass: HomeAssistant, caplog: pytest.LogCaptureFixture -) -> None: - """Test authentication error turning switch on/off.""" +async def test_action_execution_failure(hass: HomeAssistant) -> None: + """Test turning switch on/off failure.""" await setup_uptimerobot_integration(hass) entity = hass.states.get(UPTIMEROBOT_SWITCH_TEST_ENTITY) assert entity.state == STATE_ON - with patch( - "homeassistant.helpers.update_coordinator.DataUpdateCoordinator.async_request_refresh" - ) as coordinator_refresh: + with ( + patch( + "pyuptimerobot.UptimeRobot.async_edit_monitor", + side_effect=UptimeRobotException, + ), + pytest.raises(HomeAssistantError) as exc_info, + ): await hass.services.async_call( SWITCH_DOMAIN, SERVICE_TURN_ON, @@ -147,12 +150,14 @@ async def test_refresh_data( blocking=True, ) - assert coordinator_refresh.assert_called + assert exc_info.value.translation_domain == "uptimerobot" + assert exc_info.value.translation_key == "api_exception" + assert exc_info.value.translation_placeholders == { + "error": "UptimeRobotException()" + } -async def test_switch_api_failure( - hass: HomeAssistant, caplog: pytest.LogCaptureFixture -) -> None: +async def test_switch_api_failure(hass: HomeAssistant) -> None: """Test general exception turning switch on/off.""" await setup_uptimerobot_integration(hass) @@ -163,11 +168,16 @@ async def test_switch_api_failure( "pyuptimerobot.UptimeRobot.async_edit_monitor", return_value=mock_uptimerobot_api_response(key=MockApiResponseKey.ERROR), ): - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: UPTIMEROBOT_SWITCH_TEST_ENTITY}, - blocking=True, - ) + with pytest.raises(HomeAssistantError) as exc_info: + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: UPTIMEROBOT_SWITCH_TEST_ENTITY}, + blocking=True, + ) - assert "API exception" in caplog.text + assert exc_info.value.translation_domain == "uptimerobot" + assert exc_info.value.translation_key == "api_exception" + assert exc_info.value.translation_placeholders == { + "error": "test error from API." + }