Add translated exception for ESPHome action call failures (#143067)

This commit is contained in:
J. Nick Koston 2025-04-15 21:19:05 -10:00 committed by GitHub
parent f4e7ccfcfc
commit c32654db18
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 78 additions and 2 deletions

View File

@ -44,7 +44,7 @@ from homeassistant.core import (
State,
callback,
)
from homeassistant.exceptions import TemplateError
from homeassistant.exceptions import HomeAssistantError, TemplateError
from homeassistant.helpers import (
config_validation as cv,
device_registry as dr,
@ -827,7 +827,18 @@ def execute_service(
entry_data: RuntimeEntryData, service: UserService, call: ServiceCall
) -> None:
"""Execute a service on a node."""
entry_data.client.execute_service(service, call.data)
try:
entry_data.client.execute_service(service, call.data)
except APIConnectionError as err:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="action_call_failed",
translation_placeholders={
"call_name": service.name,
"device_name": entry_data.name,
"error": str(err),
},
) from err
def build_service_name(device_info: EsphomeDeviceInfo, service: UserService) -> str:

View File

@ -180,5 +180,10 @@
}
}
}
},
"exceptions": {
"action_call_failed": {
"message": "Failed to execute the action call {call_name} on {device_name}: {error}"
}
}
}

View File

@ -42,6 +42,7 @@ from homeassistant.const import (
)
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers import device_registry as dr, issue_registry as ir
from homeassistant.helpers.service_info.dhcp import DhcpServiceInfo
from homeassistant.setup import async_setup_component
@ -1123,6 +1124,65 @@ async def test_esphome_user_services_ignores_invalid_arg_types(
assert not hass.services.has_service(DOMAIN, "with_dash_bad_service")
async def test_esphome_user_service_fails(
hass: HomeAssistant,
mock_client: APIClient,
mock_esphome_device: Callable[
[APIClient, list[EntityInfo], list[UserService], list[EntityState]],
Awaitable[MockESPHomeDevice],
],
) -> None:
"""Test executing a user service fails due to disconnect."""
entity_info = []
states = []
service1 = UserService(
name="simple_service",
key=2,
args=[
UserServiceArg(name="arg1", type=UserServiceArgType.BOOL),
],
)
await mock_esphome_device(
mock_client=mock_client,
entity_info=entity_info,
user_service=[service1],
device_info={"name": "with-dash"},
states=states,
)
await hass.async_block_till_done()
assert hass.services.has_service(DOMAIN, "with_dash_simple_service")
mock_client.execute_service = Mock(side_effect=APIConnectionError("fail"))
with pytest.raises(HomeAssistantError) as exc:
await hass.services.async_call(
DOMAIN, "with_dash_simple_service", {"arg1": True}, blocking=True
)
assert exc.value.translation_domain == DOMAIN
assert exc.value.translation_key == "action_call_failed"
assert exc.value.translation_placeholders == {
"call_name": "simple_service",
"device_name": "with-dash",
"error": "fail",
}
assert (
str(exc.value)
== "Failed to execute the action call simple_service on with-dash: fail"
)
mock_client.execute_service.assert_has_calls(
[
call(
UserService(
name="simple_service",
key=2,
args=[UserServiceArg(name="arg1", type=UserServiceArgType.BOOL)],
),
{"arg1": True},
)
]
)
async def test_esphome_user_services_changes(
hass: HomeAssistant,
mock_client: APIClient,