From ec7aecef84957f11846350c7f0d53c13fb4b2248 Mon Sep 17 00:00:00 2001 From: Jan Bouwhuis Date: Mon, 18 Mar 2024 14:39:41 +0100 Subject: [PATCH] Get HomeAssistantError message from translation cache only (#113688) Get HomeAssistant error message from translation cache only --- .../components/devolo_home_network/button.py | 2 -- .../components/devolo_home_network/switch.py | 2 -- .../components/devolo_home_network/update.py | 2 -- .../components/homewizard/helpers.py | 2 -- .../components/rest_command/__init__.py | 16 +++++---- .../components/rest_command/strings.json | 6 ++-- homeassistant/components/roborock/device.py | 1 - homeassistant/components/roborock/image.py | 1 - homeassistant/components/sensibo/climate.py | 6 ---- homeassistant/components/sensibo/entity.py | 2 -- homeassistant/components/sensibo/select.py | 2 -- homeassistant/components/sensibo/switch.py | 2 -- homeassistant/components/tailwind/cover.py | 6 ---- homeassistant/components/tailwind/number.py | 1 - homeassistant/components/tessie/entity.py | 1 - .../yale_smart_alarm/alarm_control_panel.py | 3 -- .../components/yale_smart_alarm/lock.py | 2 -- tests/components/rest_command/test_init.py | 33 ++++++++++--------- tests/components/tailwind/test_cover.py | 24 ++++++++++---- tests/components/tailwind/test_number.py | 6 +++- 20 files changed, 53 insertions(+), 67 deletions(-) diff --git a/homeassistant/components/devolo_home_network/button.py b/homeassistant/components/devolo_home_network/button.py index 13e688c6fc5..1dcdc007189 100644 --- a/homeassistant/components/devolo_home_network/button.py +++ b/homeassistant/components/devolo_home_network/button.py @@ -117,14 +117,12 @@ class DevoloButtonEntity(DevoloEntity, ButtonEntity): except DevicePasswordProtected as ex: self.entry.async_start_reauth(self.hass) raise HomeAssistantError( - f"Device {self.entry.title} require re-authenticatication to set or change the password", translation_domain=DOMAIN, translation_key="password_protected", translation_placeholders={"title": self.entry.title}, ) from ex except DeviceUnavailable as ex: raise HomeAssistantError( - f"Device {self.entry.title} did not respond", translation_domain=DOMAIN, translation_key="no_response", translation_placeholders={"title": self.entry.title}, diff --git a/homeassistant/components/devolo_home_network/switch.py b/homeassistant/components/devolo_home_network/switch.py index 950b362d7f5..2a9775257a8 100644 --- a/homeassistant/components/devolo_home_network/switch.py +++ b/homeassistant/components/devolo_home_network/switch.py @@ -109,7 +109,6 @@ class DevoloSwitchEntity(DevoloCoordinatorEntity[_DataT], SwitchEntity): except DevicePasswordProtected as ex: self.entry.async_start_reauth(self.hass) raise HomeAssistantError( - f"Device {self.entry.title} require re-authenticatication to set or change the password", translation_domain=DOMAIN, translation_key="password_protected", translation_placeholders={"title": self.entry.title}, @@ -125,7 +124,6 @@ class DevoloSwitchEntity(DevoloCoordinatorEntity[_DataT], SwitchEntity): except DevicePasswordProtected as ex: self.entry.async_start_reauth(self.hass) raise HomeAssistantError( - f"Device {self.entry.title} require re-authenticatication to set or change the password", translation_domain=DOMAIN, translation_key="password_protected", translation_placeholders={"title": self.entry.title}, diff --git a/homeassistant/components/devolo_home_network/update.py b/homeassistant/components/devolo_home_network/update.py index 0793254c761..75fc1b7b99c 100644 --- a/homeassistant/components/devolo_home_network/update.py +++ b/homeassistant/components/devolo_home_network/update.py @@ -117,14 +117,12 @@ class DevoloUpdateEntity(DevoloCoordinatorEntity, UpdateEntity): except DevicePasswordProtected as ex: self.entry.async_start_reauth(self.hass) raise HomeAssistantError( - f"Device {self.entry.title} require re-authenticatication to set or change the password", translation_domain=DOMAIN, translation_key="password_protected", translation_placeholders={"title": self.entry.title}, ) from ex except DeviceUnavailable as ex: raise HomeAssistantError( - f"Device {self.entry.title} did not respond", translation_domain=DOMAIN, translation_key="no_response", translation_placeholders={"title": self.entry.title}, diff --git a/homeassistant/components/homewizard/helpers.py b/homeassistant/components/homewizard/helpers.py index a69e09204e7..a3eda4ad565 100644 --- a/homeassistant/components/homewizard/helpers.py +++ b/homeassistant/components/homewizard/helpers.py @@ -33,7 +33,6 @@ def homewizard_exception_handler( await func(self, *args, **kwargs) except RequestError as ex: raise HomeAssistantError( - "An error occurred while communicating with HomeWizard device", translation_domain=DOMAIN, translation_key="communication_error", ) from ex @@ -42,7 +41,6 @@ def homewizard_exception_handler( self.coordinator.config_entry.entry_id ) raise HomeAssistantError( - "The local API of the HomeWizard device is disabled", translation_domain=DOMAIN, translation_key="api_disabled", ) from ex diff --git a/homeassistant/components/rest_command/__init__.py b/homeassistant/components/rest_command/__init__.py index 81a57e432d2..c43e23cf068 100644 --- a/homeassistant/components/rest_command/__init__.py +++ b/homeassistant/components/rest_command/__init__.py @@ -173,33 +173,37 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: _content = await response.text() except (JSONDecodeError, AttributeError) as err: raise HomeAssistantError( - f"Response of '{request_url}' could not be decoded as JSON", translation_domain=DOMAIN, translation_key="decoding_error", - translation_placeholders={"decoding_type": "json"}, + translation_placeholders={ + "request_url": request_url, + "decoding_type": "JSON", + }, ) from err except UnicodeDecodeError as err: raise HomeAssistantError( - f"Response of '{request_url}' could not be decoded as text", translation_domain=DOMAIN, translation_key="decoding_error", - translation_placeholders={"decoding_type": "text"}, + translation_placeholders={ + "request_url": request_url, + "decoding_type": "text", + }, ) from err return {"content": _content, "status": response.status} except TimeoutError as err: raise HomeAssistantError( - f"Timeout when calling resource '{request_url}'", translation_domain=DOMAIN, translation_key="timeout", + translation_placeholders={"request_url": request_url}, ) from err except aiohttp.ClientError as err: raise HomeAssistantError( - f"Client error occurred when calling resource '{request_url}'", translation_domain=DOMAIN, translation_key="client_error", + translation_placeholders={"request_url": request_url}, ) from err # register services diff --git a/homeassistant/components/rest_command/strings.json b/homeassistant/components/rest_command/strings.json index 8a48cddace3..2d658ad8b20 100644 --- a/homeassistant/components/rest_command/strings.json +++ b/homeassistant/components/rest_command/strings.json @@ -7,13 +7,13 @@ }, "exceptions": { "timeout": { - "message": "Timeout while waiting for response from the server" + "message": "Timeout when calling resource '{request_url}'" }, "client_error": { - "message": "An error occurred while requesting the resource" + "message": "Client error occurred when calling resource '{request_url}'" }, "decoding_error": { - "message": "The response from the server could not be decoded as {decoding_type}" + "message": "The response of '{request_url}' could not be decoded as {decoding_type}" } } } diff --git a/homeassistant/components/roborock/device.py b/homeassistant/components/roborock/device.py index 01f26df56f3..7affaa396e6 100644 --- a/homeassistant/components/roborock/device.py +++ b/homeassistant/components/roborock/device.py @@ -58,7 +58,6 @@ class RoborockEntity(Entity): else: command_name = command raise HomeAssistantError( - f"Error while calling {command}", translation_domain=DOMAIN, translation_key="command_failed", translation_placeholders={ diff --git a/homeassistant/components/roborock/image.py b/homeassistant/components/roborock/image.py index f62a0aac1e4..3367f1b3017 100644 --- a/homeassistant/components/roborock/image.py +++ b/homeassistant/components/roborock/image.py @@ -105,7 +105,6 @@ class RoborockMap(RoborockCoordinatedEntity, ImageEntity): parsed_map = self.parser.parse(map_bytes) if parsed_map.image is None: raise HomeAssistantError( - "Something went wrong creating the map", translation_domain=DOMAIN, translation_key="map_failure", ) diff --git a/homeassistant/components/sensibo/climate.py b/homeassistant/components/sensibo/climate.py index d952fdb9e56..f7661a3ee80 100644 --- a/homeassistant/components/sensibo/climate.py +++ b/homeassistant/components/sensibo/climate.py @@ -314,14 +314,12 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity): """Set new target temperature.""" if "targetTemperature" not in self.device_data.active_features: raise HomeAssistantError( - "Current mode doesn't support setting Target Temperature", translation_domain=DOMAIN, translation_key="no_target_temperature_in_features", ) if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None: raise ServiceValidationError( - "No target temperature provided", translation_domain=DOMAIN, translation_key="no_target_temperature", ) @@ -341,13 +339,11 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity): """Set new target fan mode.""" if "fanLevel" not in self.device_data.active_features: raise HomeAssistantError( - "Current mode doesn't support setting Fanlevel", translation_domain=DOMAIN, translation_key="no_fan_level_in_features", ) if fan_mode not in AVAILABLE_FAN_MODES: raise HomeAssistantError( - f"Climate fan mode {fan_mode} is not supported by the integration, please open an issue", translation_domain=DOMAIN, translation_key="fan_mode_not_supported", translation_placeholders={"fan_mode": fan_mode}, @@ -393,13 +389,11 @@ class SensiboClimate(SensiboDeviceBaseEntity, ClimateEntity): """Set new target swing operation.""" if "swing" not in self.device_data.active_features: raise HomeAssistantError( - "Current mode doesn't support setting Swing", translation_domain=DOMAIN, translation_key="no_swing_in_features", ) if swing_mode not in AVAILABLE_SWING_MODES: raise HomeAssistantError( - f"Climate swing mode {swing_mode} is not supported by the integration, please open an issue", translation_domain=DOMAIN, translation_key="swing_not_supported", translation_placeholders={"swing_mode": swing_mode}, diff --git a/homeassistant/components/sensibo/entity.py b/homeassistant/components/sensibo/entity.py index 4c22ef8366a..97ef4dffca7 100644 --- a/homeassistant/components/sensibo/entity.py +++ b/homeassistant/components/sensibo/entity.py @@ -34,7 +34,6 @@ def async_handle_api_call( res = await function(entity, *args, **kwargs) except SENSIBO_ERRORS as err: raise HomeAssistantError( - str(err), translation_domain=DOMAIN, translation_key="service_raised", translation_placeholders={"error": str(err), "name": entity.name}, @@ -43,7 +42,6 @@ def async_handle_api_call( LOGGER.debug("Result %s for entity %s with arguments %s", res, entity, kwargs) if res is not True: raise HomeAssistantError( - f"Could not execute service for {entity.name}", translation_domain=DOMAIN, translation_key="service_result_not_true", translation_placeholders={"name": entity.name}, diff --git a/homeassistant/components/sensibo/select.py b/homeassistant/components/sensibo/select.py index f3f8f55fc8e..798d4735b16 100644 --- a/homeassistant/components/sensibo/select.py +++ b/homeassistant/components/sensibo/select.py @@ -100,8 +100,6 @@ class SensiboSelect(SensiboDeviceBaseEntity, SelectEntity): if self.entity_description.key not in self.device_data.active_features: hvac_mode = self.device_data.hvac_mode if self.device_data.hvac_mode else "" raise HomeAssistantError( - f"Current mode {self.device_data.hvac_mode} doesn't support setting" - f" {self.entity_description.name}", translation_domain=DOMAIN, translation_key="select_option_not_available", translation_placeholders={ diff --git a/homeassistant/components/sensibo/switch.py b/homeassistant/components/sensibo/switch.py index b4e3dbf13fd..a8ebd63fa43 100644 --- a/homeassistant/components/sensibo/switch.py +++ b/homeassistant/components/sensibo/switch.py @@ -175,8 +175,6 @@ class SensiboDeviceSwitch(SensiboDeviceBaseEntity, SwitchEntity): """Make service call to api for setting Climate React.""" if self.device_data.smart_type is None: raise HomeAssistantError( - "Use Sensibo Enable Climate React Service once to enable switch or the" - " Sensibo app", translation_domain=DOMAIN, translation_key="climate_react_not_available", ) diff --git a/homeassistant/components/tailwind/cover.py b/homeassistant/components/tailwind/cover.py index f5dba47c37e..f54902dac4a 100644 --- a/homeassistant/components/tailwind/cover.py +++ b/homeassistant/components/tailwind/cover.py @@ -71,19 +71,16 @@ class TailwindDoorCoverEntity(TailwindDoorEntity, CoverEntity): ) except TailwindDoorDisabledError as exc: raise HomeAssistantError( - str(exc), translation_domain=DOMAIN, translation_key="door_disabled", ) from exc except TailwindDoorLockedOutError as exc: raise HomeAssistantError( - str(exc), translation_domain=DOMAIN, translation_key="door_locked_out", ) from exc except TailwindError as exc: raise HomeAssistantError( - str(exc), translation_domain=DOMAIN, translation_key="communication_error", ) from exc @@ -106,19 +103,16 @@ class TailwindDoorCoverEntity(TailwindDoorEntity, CoverEntity): ) except TailwindDoorDisabledError as exc: raise HomeAssistantError( - str(exc), translation_domain=DOMAIN, translation_key="door_disabled", ) from exc except TailwindDoorLockedOutError as exc: raise HomeAssistantError( - str(exc), translation_domain=DOMAIN, translation_key="door_locked_out", ) from exc except TailwindError as exc: raise HomeAssistantError( - str(exc), translation_domain=DOMAIN, translation_key="communication_error", ) from exc diff --git a/homeassistant/components/tailwind/number.py b/homeassistant/components/tailwind/number.py index f05415e34c6..63c01cf7e73 100644 --- a/homeassistant/components/tailwind/number.py +++ b/homeassistant/components/tailwind/number.py @@ -77,7 +77,6 @@ class TailwindNumberEntity(TailwindEntity, NumberEntity): await self.entity_description.set_value_fn(self.coordinator.tailwind, value) except TailwindError as exc: raise HomeAssistantError( - str(exc), translation_domain=DOMAIN, translation_key="communication_error", ) from exc diff --git a/homeassistant/components/tessie/entity.py b/homeassistant/components/tessie/entity.py index 718a7050953..e11a99348ed 100644 --- a/homeassistant/components/tessie/entity.py +++ b/homeassistant/components/tessie/entity.py @@ -69,7 +69,6 @@ class TessieEntity(CoordinatorEntity[TessieStateUpdateCoordinator]): name: str = getattr(self, "name", self.entity_id) reason: str = response.get("reason", "unknown") raise HomeAssistantError( - reason.replace("_", " "), translation_domain=DOMAIN, translation_key=reason.replace(" ", "_"), translation_placeholders={"name": name}, diff --git a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py index e4729622a64..7cfa6ffe4b9 100644 --- a/homeassistant/components/yale_smart_alarm/alarm_control_panel.py +++ b/homeassistant/components/yale_smart_alarm/alarm_control_panel.py @@ -83,8 +83,6 @@ class YaleAlarmDevice(YaleAlarmEntity, AlarmControlPanelEntity): ) except YALE_ALL_ERRORS as error: raise HomeAssistantError( - f"Could not set alarm for {self.coordinator.entry.data[CONF_NAME]}:" - f" {error}", translation_domain=DOMAIN, translation_key="set_alarm", translation_placeholders={ @@ -98,7 +96,6 @@ class YaleAlarmDevice(YaleAlarmEntity, AlarmControlPanelEntity): self.async_write_ha_state() return raise HomeAssistantError( - "Could not change alarm, check system ready for arming", translation_domain=DOMAIN, translation_key="could_not_change_alarm", ) diff --git a/homeassistant/components/yale_smart_alarm/lock.py b/homeassistant/components/yale_smart_alarm/lock.py index 8acfecbf034..7a7b3aa4af4 100644 --- a/homeassistant/components/yale_smart_alarm/lock.py +++ b/homeassistant/components/yale_smart_alarm/lock.py @@ -80,7 +80,6 @@ class YaleDoorlock(YaleEntity, LockEntity): ) except YALE_ALL_ERRORS as error: raise HomeAssistantError( - f"Could not set lock for {self.lock_name}: {error}", translation_domain=DOMAIN, translation_key="set_lock", translation_placeholders={ @@ -94,7 +93,6 @@ class YaleDoorlock(YaleEntity, LockEntity): self.async_write_ha_state() return raise HomeAssistantError( - "Could not set lock, check system ready for lock", translation_domain=DOMAIN, translation_key="could_not_change_lock", ) diff --git a/tests/components/rest_command/test_init.py b/tests/components/rest_command/test_init.py index dc71333370a..567391a4b32 100644 --- a/tests/components/rest_command/test_init.py +++ b/tests/components/rest_command/test_init.py @@ -66,11 +66,9 @@ async def test_rest_command_timeout( aioclient_mock.get(TEST_URL, exc=TimeoutError()) - with pytest.raises( - HomeAssistantError, - match=r"^Timeout when calling resource 'https://example.com/'$", - ): + with pytest.raises(HomeAssistantError) as exc: await hass.services.async_call(DOMAIN, "get_test", {}, blocking=True) + assert str(exc.value) == "Timeout when calling resource 'https://example.com/'" assert len(aioclient_mock.mock_calls) == 1 @@ -85,12 +83,13 @@ async def test_rest_command_aiohttp_error( aioclient_mock.get(TEST_URL, exc=aiohttp.ClientError()) - with pytest.raises( - HomeAssistantError, - match=r"^Client error occurred when calling resource 'https://example.com/'$", - ): + with pytest.raises(HomeAssistantError) as exc: await hass.services.async_call(DOMAIN, "get_test", {}, blocking=True) + assert ( + str(exc.value) + == "Client error occurred when calling resource 'https://example.com/'" + ) assert len(aioclient_mock.mock_calls) == 1 @@ -336,13 +335,14 @@ async def test_rest_command_get_response_malformed_json( assert not response # Throws error when requesting response - with pytest.raises( - HomeAssistantError, - match=r"^Response of 'https://example.com/' could not be decoded as JSON$", - ): + with pytest.raises(HomeAssistantError) as exc: await hass.services.async_call( DOMAIN, "get_test", {}, blocking=True, return_response=True ) + assert ( + str(exc.value) + == "The response of 'https://example.com/' could not be decoded as JSON" + ) async def test_rest_command_get_response_none( @@ -369,12 +369,13 @@ async def test_rest_command_get_response_none( assert not response # Throws Decode error when requesting response - with pytest.raises( - HomeAssistantError, - match=r"^Response of 'https://example.com/' could not be decoded as text$", - ): + with pytest.raises(HomeAssistantError) as exc: response = await hass.services.async_call( DOMAIN, "get_test", {}, blocking=True, return_response=True ) + assert ( + str(exc.value) + == "The response of 'https://example.com/' could not be decoded as text" + ) assert not response diff --git a/tests/components/tailwind/test_cover.py b/tests/components/tailwind/test_cover.py index 5e77ed19af3..8ccb8947624 100644 --- a/tests/components/tailwind/test_cover.py +++ b/tests/components/tailwind/test_cover.py @@ -86,7 +86,7 @@ async def test_cover_operations( # Test door disabled error handling mock_tailwind.operate.side_effect = TailwindDoorDisabledError("Door disabled") - with pytest.raises(HomeAssistantError, match="Door disabled") as excinfo: + with pytest.raises(HomeAssistantError) as excinfo: await hass.services.async_call( COVER_DOMAIN, SERVICE_OPEN_COVER, @@ -95,11 +95,12 @@ async def test_cover_operations( }, blocking=True, ) + assert str(excinfo.value) == "The door is disabled and cannot be operated" assert excinfo.value.translation_domain == DOMAIN assert excinfo.value.translation_key == "door_disabled" - with pytest.raises(HomeAssistantError, match="Door disabled") as excinfo: + with pytest.raises(HomeAssistantError) as excinfo: await hass.services.async_call( COVER_DOMAIN, SERVICE_CLOSE_COVER, @@ -109,13 +110,14 @@ async def test_cover_operations( blocking=True, ) + assert str(excinfo.value) == "The door is disabled and cannot be operated" assert excinfo.value.translation_domain == DOMAIN assert excinfo.value.translation_key == "door_disabled" # Test door locked out error handling mock_tailwind.operate.side_effect = TailwindDoorLockedOutError("Door locked out") - with pytest.raises(HomeAssistantError, match="Door locked out") as excinfo: + with pytest.raises(HomeAssistantError) as excinfo: await hass.services.async_call( COVER_DOMAIN, SERVICE_OPEN_COVER, @@ -125,10 +127,11 @@ async def test_cover_operations( blocking=True, ) + assert str(excinfo.value) == "The door is locked out and cannot be operated" assert excinfo.value.translation_domain == DOMAIN assert excinfo.value.translation_key == "door_locked_out" - with pytest.raises(HomeAssistantError, match="Door locked out") as excinfo: + with pytest.raises(HomeAssistantError) as excinfo: await hass.services.async_call( COVER_DOMAIN, SERVICE_CLOSE_COVER, @@ -138,13 +141,14 @@ async def test_cover_operations( blocking=True, ) + assert str(excinfo.value) == "The door is locked out and cannot be operated" assert excinfo.value.translation_domain == DOMAIN assert excinfo.value.translation_key == "door_locked_out" # Test door error handling mock_tailwind.operate.side_effect = TailwindError("Some error") - with pytest.raises(HomeAssistantError, match="Some error") as excinfo: + with pytest.raises(HomeAssistantError) as excinfo: await hass.services.async_call( COVER_DOMAIN, SERVICE_OPEN_COVER, @@ -154,10 +158,14 @@ async def test_cover_operations( blocking=True, ) + assert ( + str(excinfo.value) + == "An error occurred while communicating with the Tailwind device" + ) assert excinfo.value.translation_domain == DOMAIN assert excinfo.value.translation_key == "communication_error" - with pytest.raises(HomeAssistantError, match="Some error") as excinfo: + with pytest.raises(HomeAssistantError) as excinfo: await hass.services.async_call( COVER_DOMAIN, SERVICE_CLOSE_COVER, @@ -167,5 +175,9 @@ async def test_cover_operations( blocking=True, ) + assert ( + str(excinfo.value) + == "An error occurred while communicating with the Tailwind device" + ) assert excinfo.value.translation_domain == DOMAIN assert excinfo.value.translation_key == "communication_error" diff --git a/tests/components/tailwind/test_number.py b/tests/components/tailwind/test_number.py index 84d22eebd85..4e6736fc831 100644 --- a/tests/components/tailwind/test_number.py +++ b/tests/components/tailwind/test_number.py @@ -52,7 +52,7 @@ async def test_number_entities( # Test error handling mock_tailwind.status_led.side_effect = TailwindError("Some error") - with pytest.raises(HomeAssistantError, match="Some error") as excinfo: + with pytest.raises(HomeAssistantError) as excinfo: await hass.services.async_call( number.DOMAIN, SERVICE_SET_VALUE, @@ -63,5 +63,9 @@ async def test_number_entities( blocking=True, ) + assert ( + str(excinfo.value) + == "An error occurred while communicating with the Tailwind device" + ) assert excinfo.value.translation_domain == DOMAIN assert excinfo.value.translation_key == "communication_error"