Raise HomeAssistantError for pyLoad action failures (#184061)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
epenet
2026-10-02 15:39:37 +02:00
committed by GitHub
co-authored by Claude Opus 5.5
parent 2ebbbcebe9
commit c4035b579c
5 changed files with 59 additions and 27 deletions
+9 -4
View File
@@ -5,11 +5,11 @@ from dataclasses import dataclass
from enum import StrEnum
from typing import Any, override
from pyloadapi import CannotConnect, InvalidAuth, PyLoadAPI
from pyloadapi import CannotConnect, InvalidAuth, ParserError, PyLoadAPI
from homeassistant.components.button import ButtonEntity, ButtonEntityDescription
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN
@@ -86,12 +86,17 @@ class PyLoadBinarySensor(BasePyLoadEntity, ButtonEntity):
try:
await self.entity_description.press_fn(self.coordinator.pyload)
except CannotConnect as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_exception",
) from e
except InvalidAuth as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_auth_exception",
) from e
except ParserError as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="setup_parse_exception",
) from e
@@ -32,9 +32,7 @@ rules:
unique-config-entry: done
# Silver
action-exceptions:
status: exempt
comment: The integration registers no actions.
action-exceptions: done
config-entry-unloading: done
docs-configuration-parameters:
status: exempt
+23 -8
View File
@@ -5,7 +5,7 @@ from dataclasses import dataclass
from enum import StrEnum
from typing import Any, override
from pyloadapi import CannotConnect, InvalidAuth, PyLoadAPI
from pyloadapi import CannotConnect, InvalidAuth, ParserError, PyLoadAPI
from homeassistant.components.switch import (
SwitchDeviceClass,
@@ -13,7 +13,7 @@ from homeassistant.components.switch import (
SwitchEntityDescription,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DOMAIN
@@ -96,15 +96,20 @@ class PyLoadSwitchEntity(BasePyLoadEntity, SwitchEntity):
try:
await self.entity_description.turn_on_fn(self.coordinator.pyload)
except CannotConnect as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_exception",
) from e
except InvalidAuth as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_auth_exception",
) from e
except ParserError as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="setup_parse_exception",
) from e
await self.coordinator.async_refresh()
@@ -114,15 +119,20 @@ class PyLoadSwitchEntity(BasePyLoadEntity, SwitchEntity):
try:
await self.entity_description.turn_off_fn(self.coordinator.pyload)
except CannotConnect as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_exception",
) from e
except InvalidAuth as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_auth_exception",
) from e
except ParserError as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="setup_parse_exception",
) from e
await self.coordinator.async_refresh()
@@ -132,14 +142,19 @@ class PyLoadSwitchEntity(BasePyLoadEntity, SwitchEntity):
try:
await self.entity_description.toggle_fn(self.coordinator.pyload)
except CannotConnect as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_exception",
) from e
except InvalidAuth as e:
raise ServiceValidationError(
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="service_call_auth_exception",
) from e
except ParserError as e:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="setup_parse_exception",
) from e
await self.coordinator.async_refresh()
+13 -6
View File
@@ -3,7 +3,7 @@
from collections.abc import Generator
from unittest.mock import AsyncMock, call, patch
from pyloadapi import CannotConnect, InvalidAuth
from pyloadapi import CannotConnect, InvalidAuth, ParserError
import pytest
from syrupy.assertion import SnapshotAssertion
@@ -12,7 +12,7 @@ from homeassistant.components.pyload.button import PyLoadButtonEntity
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from tests.common import MockConfigEntry, snapshot_platform
@@ -85,8 +85,12 @@ async def test_button_press(
@pytest.mark.parametrize(
("side_effect"),
[CannotConnect, InvalidAuth],
("side_effect", "translation_key"),
[
pytest.param(CannotConnect, "service_call_exception", id="cannot_connect"),
pytest.param(InvalidAuth, "service_call_auth_exception", id="invalid_auth"),
pytest.param(ParserError, "setup_parse_exception", id="parser_error"),
],
)
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_button_press_errors(
@@ -94,7 +98,8 @@ async def test_button_press_errors(
config_entry: MockConfigEntry,
mock_pyloadapi: AsyncMock,
entity_registry: er.EntityRegistry,
side_effect: Exception,
side_effect: type[Exception],
translation_key: str,
) -> None:
"""Test button press method."""
@@ -113,10 +118,12 @@ async def test_button_press_errors(
mock_pyloadapi.restart.side_effect = side_effect
for entity_entry in entity_entries:
with pytest.raises(ServiceValidationError):
with pytest.raises(HomeAssistantError) as exc_info:
await hass.services.async_call(
BUTTON_DOMAIN,
SERVICE_PRESS,
{ATTR_ENTITY_ID: entity_entry.entity_id},
blocking=True,
)
assert type(exc_info.value) is HomeAssistantError
assert exc_info.value.translation_key == translation_key
+13 -6
View File
@@ -3,7 +3,7 @@
from collections.abc import Generator
from unittest.mock import AsyncMock, call, patch
from pyloadapi import CannotConnect, InvalidAuth
from pyloadapi import CannotConnect, InvalidAuth, ParserError
import pytest
from syrupy.assertion import SnapshotAssertion
@@ -17,7 +17,7 @@ from homeassistant.components.switch import (
from homeassistant.config_entries import ConfigEntryState
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import entity_registry as er
from tests.common import MockConfigEntry, snapshot_platform
@@ -115,8 +115,12 @@ async def test_turn_on_off(
],
)
@pytest.mark.parametrize(
("side_effect"),
[CannotConnect, InvalidAuth],
("side_effect", "translation_key"),
[
pytest.param(CannotConnect, "service_call_exception", id="cannot_connect"),
pytest.param(InvalidAuth, "service_call_auth_exception", id="invalid_auth"),
pytest.param(ParserError, "setup_parse_exception", id="parser_error"),
],
)
async def test_turn_on_off_errors(
hass: HomeAssistant,
@@ -124,7 +128,8 @@ async def test_turn_on_off_errors(
mock_pyloadapi: AsyncMock,
service_call: str,
entity_registry: er.EntityRegistry,
side_effect: Exception,
side_effect: type[Exception],
translation_key: str,
) -> None:
"""Test switch turn on/off, toggle method."""
@@ -143,10 +148,12 @@ async def test_turn_on_off_errors(
mock_pyloadapi.toggle_reconnect.side_effect = side_effect
for entity_entry in entity_entries:
with pytest.raises(ServiceValidationError):
with pytest.raises(HomeAssistantError) as exc_info:
await hass.services.async_call(
SWITCH_DOMAIN,
service_call,
{ATTR_ENTITY_ID: entity_entry.entity_id},
blocking=True,
)
assert type(exc_info.value) is HomeAssistantError
assert exc_info.value.translation_key == translation_key