Improve error handling in /api/states POST (#99810)

This commit is contained in:
Erik Montnemery 2023-09-07 13:33:38 +02:00 committed by GitHub
parent eee5705458
commit 368acaf6fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 5 deletions

View File

@ -30,7 +30,13 @@ from homeassistant.const import (
)
import homeassistant.core as ha
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceNotFound, TemplateError, Unauthorized
from homeassistant.exceptions import (
InvalidEntityFormatError,
InvalidStateError,
ServiceNotFound,
TemplateError,
Unauthorized,
)
from homeassistant.helpers import config_validation as cv, template
from homeassistant.helpers.json import json_dumps
from homeassistant.helpers.service import async_get_all_descriptions
@ -236,7 +242,7 @@ class APIEntityStateView(HomeAssistantView):
"""Update state of entity."""
if not request["hass_user"].is_admin:
raise Unauthorized(entity_id=entity_id)
hass = request.app["hass"]
hass: HomeAssistant = request.app["hass"]
try:
data = await request.json()
except ValueError:
@ -251,9 +257,16 @@ class APIEntityStateView(HomeAssistantView):
is_new_state = hass.states.get(entity_id) is None
# Write state
try:
hass.states.async_set(
entity_id, new_state, attributes, force_update, self.context(request)
)
except InvalidEntityFormatError:
return self.json_message(
"Invalid entity ID specified.", HTTPStatus.BAD_REQUEST
)
except InvalidStateError:
return self.json_message("Invalid state specified.", HTTPStatus.BAD_REQUEST)
# Read the state back for our response
status_code = HTTPStatus.CREATED if is_new_state else HTTPStatus.OK

View File

@ -97,6 +97,28 @@ async def test_api_state_change_of_non_existing_entity(
assert hass.states.get("test_entity.that_does_not_exist").state == new_state
async def test_api_state_change_with_bad_entity_id(
hass: HomeAssistant, mock_api_client: TestClient
) -> None:
"""Test if API sends appropriate error if we omit state."""
resp = await mock_api_client.post(
"/api/states/bad.entity.id", json={"state": "new_state"}
)
assert resp.status == HTTPStatus.BAD_REQUEST
async def test_api_state_change_with_bad_state(
hass: HomeAssistant, mock_api_client: TestClient
) -> None:
"""Test if API sends appropriate error if we omit state."""
resp = await mock_api_client.post(
"/api/states/test.test", json={"state": "x" * 256}
)
assert resp.status == HTTPStatus.BAD_REQUEST
async def test_api_state_change_with_bad_data(
hass: HomeAssistant, mock_api_client: TestClient
) -> None: