From c81a4f863389c4d7106e61083c041b6152617585 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Fri, 27 Sep 2024 19:23:24 +0200 Subject: [PATCH] =?UTF-8?q?Translate=20exception=20from=20fj=C3=A4r=C3=A5s?= =?UTF-8?q?kupan=20(#126673)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/fjaraskupan/coordinator.py | 51 ++++++++++++++++--- .../components/fjaraskupan/strings.json | 14 +++++ .../fjaraskupan/test_coordinator.py | 33 ++++++++++++ 3 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 tests/components/fjaraskupan/test_coordinator.py diff --git a/homeassistant/components/fjaraskupan/coordinator.py b/homeassistant/components/fjaraskupan/coordinator.py index 22811ce534b..90b2c617239 100644 --- a/homeassistant/components/fjaraskupan/coordinator.py +++ b/homeassistant/components/fjaraskupan/coordinator.py @@ -3,11 +3,18 @@ from __future__ import annotations from collections.abc import AsyncIterator -from contextlib import asynccontextmanager +from contextlib import asynccontextmanager, contextmanager from datetime import timedelta import logging -from fjaraskupan import Device, State +from fjaraskupan import ( + Device, + FjaraskupanConnectionError, + FjaraskupanError, + FjaraskupanReadError, + FjaraskupanWriteError, + State, +) from homeassistant.components.bluetooth import ( BluetoothServiceInfoBleak, @@ -19,9 +26,37 @@ from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed +from .const import DOMAIN + _LOGGER = logging.getLogger(__name__) +@contextmanager +def exception_converter(): + """Convert exception so home assistant translated ones.""" + + try: + yield + except FjaraskupanWriteError as exception: + raise HomeAssistantError( + translation_domain=DOMAIN, translation_key="write_error" + ) from exception + except FjaraskupanReadError as exception: + raise HomeAssistantError( + translation_domain=DOMAIN, translation_key="read_error" + ) from exception + except FjaraskupanConnectionError as exception: + raise HomeAssistantError( + translation_domain=DOMAIN, translation_key="connection_error" + ) from exception + except FjaraskupanError as exception: + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="unexpected_error", + translation_placeholders={"msg": str(exception)}, + ) from exception + + class UnableToConnect(HomeAssistantError): """Exception to indicate that we cannot connect to device.""" @@ -71,8 +106,11 @@ class FjaraskupanCoordinator(DataUpdateCoordinator[State]): ) ) is None: raise UpdateFailed("No connectable path to device") - async with self.device.connect(ble_device) as device: - await device.update() + + with exception_converter(): + async with self.device.connect(ble_device) as device: + await device.update() + return self.device.state def detection_callback(self, service_info: BluetoothServiceInfoBleak) -> None: @@ -90,7 +128,8 @@ class FjaraskupanCoordinator(DataUpdateCoordinator[State]): ) is None: raise UnableToConnect("No connectable path to device") - async with self.device.connect(ble_device) as device: - yield device + with exception_converter(): + async with self.device.connect(ble_device) as device: + yield device self.async_set_updated_data(self.device.state) diff --git a/homeassistant/components/fjaraskupan/strings.json b/homeassistant/components/fjaraskupan/strings.json index d91cc47dea1..024152a0a00 100644 --- a/homeassistant/components/fjaraskupan/strings.json +++ b/homeassistant/components/fjaraskupan/strings.json @@ -24,5 +24,19 @@ "name": "Periodic venting" } } + }, + "exceptions": { + "write_error": { + "message": "Failed to write data to device" + }, + "read_error": { + "message": "Failed to read data from device" + }, + "connection_error": { + "message": "Failed to connect to device" + }, + "unexpected_error": { + "message": "Unexpected error occurred: {msg}" + } } } diff --git a/tests/components/fjaraskupan/test_coordinator.py b/tests/components/fjaraskupan/test_coordinator.py new file mode 100644 index 00000000000..e63d52a7594 --- /dev/null +++ b/tests/components/fjaraskupan/test_coordinator.py @@ -0,0 +1,33 @@ +"""Test the Fjäråskupan coordinator module.""" + +from fjaraskupan import ( + FjaraskupanConnectionError, + FjaraskupanError, + FjaraskupanReadError, + FjaraskupanWriteError, +) +import pytest + +from homeassistant.components.fjaraskupan.const import DOMAIN +from homeassistant.components.fjaraskupan.coordinator import exception_converter +from homeassistant.exceptions import HomeAssistantError + + +@pytest.mark.parametrize( + ("exception", "translation_key", "translation_placeholder"), + [ + (FjaraskupanReadError(), "read_error", None), + (FjaraskupanWriteError(), "write_error", None), + (FjaraskupanConnectionError(), "connection_error", None), + (FjaraskupanError("Some error"), "unexpected_error", {"msg": "Some error"}), + ], +) +def test_exeception_wrapper( + exception: Exception, translation_key: str, translation_placeholder: dict[str, str] +) -> None: + """Test our exception conversion.""" + with pytest.raises(HomeAssistantError) as exc_info, exception_converter(): + raise exception + assert exc_info.value.translation_domain == DOMAIN + assert exc_info.value.translation_key == translation_key + assert exc_info.value.translation_placeholders == translation_placeholder