mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Add exception translation to NUT (#141629)
* Add exception translation and test cases * Capitalize ID in error string * Test translation placeholders, simplify test cases
This commit is contained in:
parent
ef06d2c06e
commit
2121b943a3
@ -79,9 +79,21 @@ async def async_setup_entry(hass: HomeAssistant, entry: NutConfigEntry) -> bool:
|
||||
try:
|
||||
return await data.async_update()
|
||||
except NUTLoginError as err:
|
||||
raise ConfigEntryAuthFailed from err
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="device_authentication",
|
||||
translation_placeholders={
|
||||
"err": str(err),
|
||||
},
|
||||
) from err
|
||||
except NUTError as err:
|
||||
raise UpdateFailed(f"Error fetching UPS state: {err}") from err
|
||||
raise UpdateFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="data_fetch_error",
|
||||
translation_placeholders={
|
||||
"err": str(err),
|
||||
},
|
||||
) from err
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
hass,
|
||||
@ -328,7 +340,12 @@ class PyNUTData:
|
||||
await self._client.run_command(self._alias, command_name)
|
||||
except NUTError as err:
|
||||
raise HomeAssistantError(
|
||||
f"Error running command {command_name}, {err}"
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="nut_command_error",
|
||||
translation_placeholders={
|
||||
"command_name": command_name,
|
||||
"err": str(err),
|
||||
},
|
||||
) from err
|
||||
|
||||
async def async_list_commands(self) -> set[str] | None:
|
||||
|
@ -51,7 +51,11 @@ async def async_call_action_from_config(
|
||||
runtime_data = _get_runtime_data_from_device_id(hass, device_id)
|
||||
if not runtime_data:
|
||||
raise InvalidDeviceAutomationConfig(
|
||||
f"Unable to find a NUT device with id {device_id}"
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="device_invalid",
|
||||
translation_placeholders={
|
||||
"device_id": device_id,
|
||||
},
|
||||
)
|
||||
await runtime_data.data.async_run_command(command_name)
|
||||
|
||||
|
@ -217,5 +217,19 @@
|
||||
"switch": {
|
||||
"outlet_number_load_poweronoff": { "name": "Power outlet {outlet_name}" }
|
||||
}
|
||||
},
|
||||
"exceptions": {
|
||||
"data_fetch_error": {
|
||||
"message": "Error fetching UPS state: {err}"
|
||||
},
|
||||
"device_authentication": {
|
||||
"message": "Device authentication error: {err}"
|
||||
},
|
||||
"device_invalid": {
|
||||
"message": "Unable to find a NUT device with ID {device_id}"
|
||||
},
|
||||
"nut_command_error": {
|
||||
"message": "Error running command {command_name}, {err}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ from homeassistant.components.nut import DOMAIN
|
||||
from homeassistant.components.nut.const import INTEGRATION_SUPPORTED_COMMANDS
|
||||
from homeassistant.const import CONF_DEVICE_ID, CONF_TYPE
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
@ -191,48 +192,39 @@ async def test_action(hass: HomeAssistant, device_registry: dr.DeviceRegistry) -
|
||||
run_command.assert_called_with("someUps", "beeper.disable")
|
||||
|
||||
|
||||
async def test_rund_command_exception(
|
||||
async def test_run_command_exception(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test logged error if run command raises exception."""
|
||||
"""Test if run command raises exception with translation."""
|
||||
|
||||
list_commands_return_value = {"beeper.enable": None}
|
||||
error_message = "Something wrong happened"
|
||||
run_command = AsyncMock(side_effect=NUTError(error_message))
|
||||
command_name = "beeper.enable"
|
||||
nut_error_message = "Something wrong happened"
|
||||
run_command = AsyncMock(side_effect=NUTError(nut_error_message))
|
||||
await async_init_integration(
|
||||
hass,
|
||||
list_vars={"ups.status": "OL"},
|
||||
list_commands_return_value=list_commands_return_value,
|
||||
list_ups={"ups1": "UPS 1"},
|
||||
list_commands_return_value={command_name: None},
|
||||
run_command=run_command,
|
||||
)
|
||||
device_entry = next(device for device in device_registry.devices.values())
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "event",
|
||||
"event_type": "test_some_event",
|
||||
},
|
||||
"action": {
|
||||
"domain": DOMAIN,
|
||||
"device_id": device_entry.id,
|
||||
"type": "beeper_enable",
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
platform = await device_automation.async_get_device_automation_platform(
|
||||
hass, DOMAIN, DeviceAutomationType.ACTION
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_some_event")
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert error_message in caplog.text
|
||||
error_message = f"Error running command {command_name}, {nut_error_message}"
|
||||
with pytest.raises(HomeAssistantError, match=error_message):
|
||||
await platform.async_call_action_from_config(
|
||||
hass,
|
||||
{
|
||||
CONF_TYPE: command_name,
|
||||
CONF_DEVICE_ID: device_entry.id,
|
||||
},
|
||||
{},
|
||||
None,
|
||||
)
|
||||
|
||||
|
||||
async def test_action_exception_invalid_device(hass: HomeAssistant) -> None:
|
||||
@ -248,10 +240,12 @@ async def test_action_exception_invalid_device(hass: HomeAssistant) -> None:
|
||||
hass, DOMAIN, DeviceAutomationType.ACTION
|
||||
)
|
||||
|
||||
with pytest.raises(InvalidDeviceAutomationConfig):
|
||||
device_id = "invalid_device_id"
|
||||
error_message = f"Unable to find a NUT device with ID {device_id}"
|
||||
with pytest.raises(InvalidDeviceAutomationConfig, match=error_message):
|
||||
await platform.async_call_action_from_config(
|
||||
hass,
|
||||
{CONF_TYPE: "beeper.enable", CONF_DEVICE_ID: "invalid_device_id"},
|
||||
{CONF_TYPE: "beeper.enable", CONF_DEVICE_ID: device_id},
|
||||
{},
|
||||
None,
|
||||
)
|
||||
|
@ -4,6 +4,7 @@ from copy import deepcopy
|
||||
from unittest.mock import patch
|
||||
|
||||
from aionut import NUTError, NUTLoginError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.nut.const import DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
@ -56,7 +57,10 @@ async def test_async_setup_entry(hass: HomeAssistant) -> None:
|
||||
assert not hass.data.get(DOMAIN)
|
||||
|
||||
|
||||
async def test_config_not_ready(hass: HomeAssistant) -> None:
|
||||
async def test_config_not_ready(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test for setup failure if connection to broker is missing."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
@ -64,6 +68,8 @@ async def test_config_not_ready(hass: HomeAssistant) -> None:
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
nut_error_message = "Something wrong happened"
|
||||
error_message = f"Error fetching UPS state: {nut_error_message}"
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.nut.AIONUTClient.list_ups",
|
||||
@ -71,15 +77,20 @@ async def test_config_not_ready(hass: HomeAssistant) -> None:
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.nut.AIONUTClient.list_vars",
|
||||
side_effect=NUTError,
|
||||
side_effect=NUTError(nut_error_message),
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
assert error_message in caplog.text
|
||||
|
||||
async def test_auth_fails(hass: HomeAssistant) -> None:
|
||||
|
||||
async def test_auth_fails(
|
||||
hass: HomeAssistant,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test for setup failure if auth has changed."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN,
|
||||
@ -87,6 +98,8 @@ async def test_auth_fails(hass: HomeAssistant) -> None:
|
||||
)
|
||||
entry.add_to_hass(hass)
|
||||
|
||||
nut_error_message = "Something wrong happened"
|
||||
error_message = f"Device authentication error: {nut_error_message}"
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.nut.AIONUTClient.list_ups",
|
||||
@ -94,13 +107,15 @@ async def test_auth_fails(hass: HomeAssistant) -> None:
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.nut.AIONUTClient.list_vars",
|
||||
side_effect=NUTLoginError,
|
||||
side_effect=NUTLoginError(nut_error_message),
|
||||
),
|
||||
):
|
||||
await hass.config_entries.async_setup(entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
assert entry.state is ConfigEntryState.SETUP_ERROR
|
||||
|
||||
assert error_message in caplog.text
|
||||
|
||||
flows = hass.config_entries.flow.async_progress()
|
||||
assert len(flows) == 1
|
||||
assert flows[0]["context"]["source"] == "reauth"
|
||||
|
Loading…
x
Reference in New Issue
Block a user