diff --git a/homeassistant/components/todo/__init__.py b/homeassistant/components/todo/__init__.py index 0f39d38eb46..afcb8e28f74 100644 --- a/homeassistant/components/todo/__init__.py +++ b/homeassistant/components/todo/__init__.py @@ -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) diff --git a/homeassistant/components/todo/strings.json b/homeassistant/components/todo/strings.json index 3da921a8f47..5ef7a5fe35b 100644 --- a/homeassistant/components/todo/strings.json +++ b/homeassistant/components/todo/strings.json @@ -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}" + } } } diff --git a/tests/components/shopping_list/test_todo.py b/tests/components/shopping_list/test_todo.py index 7722bd8b6da..373c449497c 100644 --- a/tests/components/shopping_list/test_todo.py +++ b/tests/components/shopping_list/test_todo.py @@ -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", diff --git a/tests/components/todo/test_init.py b/tests/components/todo/test_init.py index e1440b292ee..5a8f6183cbb 100644 --- a/tests/components/todo/test_init.py +++ b/tests/components/todo/test_init.py @@ -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",