Improve To-do service error handling (#106886)

This commit is contained in:
Allen Porter 2024-01-02 10:50:28 -08:00 committed by GitHub
parent afed45d5d0
commit 943fb2791e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 13 deletions

View file

@ -19,7 +19,7 @@ from homeassistant.core import (
SupportsResponse,
callback,
)
from homeassistant.exceptions import HomeAssistantError
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.config_validation import ( # noqa: F401
PLATFORM_SCHEMA,
@ -106,8 +106,11 @@ def _validate_supported_features(
if desc.service_field not in call_data:
continue
if not supported_features or not supported_features & desc.required_feature:
raise ValueError(
f"Entity does not support setting field '{desc.service_field}'"
raise ServiceValidationError(
f"Entity does not support setting field '{desc.service_field}'",
translation_domain=DOMAIN,
translation_key="update_field_not_supported",
translation_placeholders={"service_field": desc.service_field},
)
@ -481,7 +484,12 @@ async def _async_update_todo_item(entity: TodoListEntity, call: ServiceCall) ->
item = call.data["item"]
found = _find_by_uid_or_summary(item, entity.todo_items)
if not found:
raise ValueError(f"Unable to find To-do item '{item}'")
raise ServiceValidationError(
f"Unable to find To-do item '{item}'",
translation_domain=DOMAIN,
translation_key="item_not_found",
translation_placeholders={"item": item},
)
_validate_supported_features(entity.supported_features, call.data)
@ -509,7 +517,12 @@ async def _async_remove_todo_items(entity: TodoListEntity, call: ServiceCall) ->
for item in call.data.get("item", []):
found = _find_by_uid_or_summary(item, entity.todo_items)
if not found or not found.uid:
raise ValueError(f"Unable to find To-do item '{item}")
raise ServiceValidationError(
f"Unable to find To-do item '{item}'",
translation_domain=DOMAIN,
translation_key="item_not_found",
translation_placeholders={"item": item},
)
uids.append(found.uid)
await entity.async_delete_todo_items(uids=uids)

View file

@ -90,5 +90,13 @@
"completed": "Completed"
}
}
},
"exceptions": {
"item_not_found": {
"message": "Unable to find To-do item: {item}"
},
"update_field_not_supported": {
"message": "Entity does not support setting field: {service_field}"
}
}
}

View file

@ -7,6 +7,7 @@ import pytest
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from tests.typing import WebSocketGenerator
@ -338,7 +339,7 @@ async def test_update_invalid_item(
) -> None:
"""Test updating a todo item that does not exist."""
with pytest.raises(ValueError, match="Unable to find"):
with pytest.raises(ServiceValidationError, match="Unable to find"):
await hass.services.async_call(
TODO_DOMAIN,
"update_item",

View file

@ -20,7 +20,7 @@ from homeassistant.components.todo import (
from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import intent
from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -347,12 +347,12 @@ async def test_add_item_service_raises(
({"item": ""}, vol.Invalid, "length of value must be at least 1"),
(
{"item": "Submit forms", "description": "Submit tax forms"},
ValueError,
ServiceValidationError,
"does not support setting field 'description'",
),
(
{"item": "Submit forms", "due_date": "2023-11-17"},
ValueError,
ServiceValidationError,
"does not support setting field 'due_date'",
),
(
@ -360,7 +360,7 @@ async def test_add_item_service_raises(
"item": "Submit forms",
"due_datetime": f"2023-11-17T17:00:00{TEST_OFFSET}",
},
ValueError,
ServiceValidationError,
"does not support setting field 'due_datetime'",
),
],
@ -622,7 +622,7 @@ async def test_update_todo_item_service_by_summary_not_found(
await create_mock_platform(hass, [test_entity])
with pytest.raises(ValueError, match="Unable to find"):
with pytest.raises(ServiceValidationError, match="Unable to find"):
await hass.services.async_call(
DOMAIN,
"update_item",
@ -681,7 +681,7 @@ async def test_update_todo_item_field_unsupported(
await create_mock_platform(hass, [test_entity])
with pytest.raises(ValueError, match="does not support"):
with pytest.raises(ServiceValidationError, match="does not support"):
await hass.services.async_call(
DOMAIN,
"update_item",
@ -931,7 +931,7 @@ async def test_remove_todo_item_service_by_summary_not_found(
await create_mock_platform(hass, [test_entity])
with pytest.raises(ValueError, match="Unable to find"):
with pytest.raises(ServiceValidationError, match="Unable to find"):
await hass.services.async_call(
DOMAIN,
"remove_item",