From 7bdd64a3f7b56481d3d3b0fe7b2ff3e2918f3204 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 2 Jul 2023 21:47:25 -0500 Subject: [PATCH] Handle invalid utf-8 from the ESPHome dashboard (#95743) If the yaml file has invalid utf-8, the config flow would raise an unhandled exception. Allow the encryption key to be entered manually in this case instead of a hard failure fixes #92772 --- homeassistant/components/esphome/config_flow.py | 6 ++++++ tests/components/esphome/test_config_flow.py | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/esphome/config_flow.py b/homeassistant/components/esphome/config_flow.py index 53c8577be44..731743e48c8 100644 --- a/homeassistant/components/esphome/config_flow.py +++ b/homeassistant/components/esphome/config_flow.py @@ -3,6 +3,7 @@ from __future__ import annotations from collections import OrderedDict from collections.abc import Mapping +import json import logging from typing import Any @@ -408,6 +409,11 @@ class EsphomeFlowHandler(ConfigFlow, domain=DOMAIN): except aiohttp.ClientError as err: _LOGGER.error("Error talking to the dashboard: %s", err) return False + except json.JSONDecodeError as err: + _LOGGER.error( + "Error parsing response from dashboard: %s", err, exc_info=True + ) + return False self._noise_psk = noise_psk return True diff --git a/tests/components/esphome/test_config_flow.py b/tests/components/esphome/test_config_flow.py index 4a99de77c1a..662816a53d8 100644 --- a/tests/components/esphome/test_config_flow.py +++ b/tests/components/esphome/test_config_flow.py @@ -1,5 +1,6 @@ """Test config flow.""" import asyncio +import json from unittest.mock import AsyncMock, MagicMock, patch from aioesphomeapi import ( @@ -414,8 +415,13 @@ async def test_user_discovers_name_and_gets_key_from_dashboard( assert mock_client.noise_psk == VALID_NOISE_PSK +@pytest.mark.parametrize( + "dashboard_exception", + [aiohttp.ClientError(), json.JSONDecodeError("test", "test", 0)], +) async def test_user_discovers_name_and_gets_key_from_dashboard_fails( hass: HomeAssistant, + dashboard_exception: Exception, mock_client, mock_dashboard, mock_zeroconf: None, @@ -442,7 +448,7 @@ async def test_user_discovers_name_and_gets_key_from_dashboard_fails( with patch( "homeassistant.components.esphome.dashboard.ESPHomeDashboardAPI.get_encryption_key", - side_effect=aiohttp.ClientError, + side_effect=dashboard_exception, ): result = await hass.config_entries.flow.async_init( "esphome",