Translate exception from fjäråskupan (#126673)

This commit is contained in:
Joakim Plate 2024-09-27 19:23:24 +02:00 committed by GitHub
parent 4599d1650b
commit c81a4f8633
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 92 additions and 6 deletions

View File

@ -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)

View File

@ -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}"
}
}
}

View File

@ -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