From 9c0856787d6b8464b51763dfb0b1abcdd20e5123 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 31 Jan 2023 14:37:26 -0500 Subject: [PATCH] Improve JSON errors from HTTP view (#87042) --- homeassistant/components/http/view.py | 13 +++++++++++-- tests/components/http/test_view.py | 15 ++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/homeassistant/components/http/view.py b/homeassistant/components/http/view.py index 6e17f76b629..98d86ba3524 100644 --- a/homeassistant/components/http/view.py +++ b/homeassistant/components/http/view.py @@ -20,7 +20,11 @@ import voluptuous as vol from homeassistant import exceptions from homeassistant.const import CONTENT_TYPE_JSON from homeassistant.core import Context, is_callback -from homeassistant.helpers.json import JSON_ENCODE_EXCEPTIONS, json_bytes +from homeassistant.helpers.json import JSON_ENCODE_EXCEPTIONS, json_bytes, json_dumps +from homeassistant.util.json import ( + find_paths_unserializable_data, + format_unserializable_data, +) from .const import KEY_AUTHENTICATED, KEY_HASS @@ -54,7 +58,12 @@ class HomeAssistantView: try: msg = json_bytes(result) except JSON_ENCODE_EXCEPTIONS as err: - _LOGGER.error("Unable to serialize to JSON: %s\n%s", err, result) + _LOGGER.error( + "Unable to serialize to JSON. Bad data found at %s", + format_unserializable_data( + find_paths_unserializable_data(result, dump=json_dumps) + ), + ) raise HTTPInternalServerError from err response = web.Response( body=msg, diff --git a/tests/components/http/test_view.py b/tests/components/http/test_view.py index f6a2ff85d3a..4709806fedd 100644 --- a/tests/components/http/test_view.py +++ b/tests/components/http/test_view.py @@ -1,4 +1,5 @@ """Tests for Home Assistant View.""" +from decimal import Decimal from http import HTTPStatus import json from unittest.mock import AsyncMock, Mock @@ -32,18 +33,18 @@ def mock_request_with_stopping(): async def test_invalid_json(caplog): """Test trying to return invalid JSON.""" - view = HomeAssistantView() - with pytest.raises(HTTPInternalServerError): - view.json(rb"\ud800") + HomeAssistantView.json({"hello": Decimal("2.0")}) - assert "Unable to serialize to JSON" in caplog.text + assert ( + "Unable to serialize to JSON. Bad data found at $.hello=2.0(" + in caplog.text + ) -async def test_nan_serialized_to_null(caplog): +async def test_nan_serialized_to_null(): """Test nan serialized to null JSON.""" - view = HomeAssistantView() - response = view.json(float("NaN")) + response = HomeAssistantView.json(float("NaN")) assert json.loads(response.body.decode("utf-8")) is None