From ab9ed0eba4fa2e7d9134a6d639ed50a947b258b7 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Thu, 16 May 2024 13:43:03 +0200 Subject: [PATCH] Handle uncaught exceptions in Analytics insights (#117558) --- .../analytics_insights/config_flow.py | 3 ++ .../analytics_insights/strings.json | 3 +- .../analytics_insights/test_config_flow.py | 28 ++++++++++++------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/analytics_insights/config_flow.py b/homeassistant/components/analytics_insights/config_flow.py index cef5ac2e9e57e3..909290b10355db 100644 --- a/homeassistant/components/analytics_insights/config_flow.py +++ b/homeassistant/components/analytics_insights/config_flow.py @@ -82,6 +82,9 @@ async def async_step_user( except HomeassistantAnalyticsConnectionError: LOGGER.exception("Error connecting to Home Assistant analytics") return self.async_abort(reason="cannot_connect") + except Exception: # noqa: BLE001 + LOGGER.exception("Unexpected error") + return self.async_abort(reason="unknown") options = [ SelectOptionDict( diff --git a/homeassistant/components/analytics_insights/strings.json b/homeassistant/components/analytics_insights/strings.json index 00c9cfa44043e7..3b770f189a41be 100644 --- a/homeassistant/components/analytics_insights/strings.json +++ b/homeassistant/components/analytics_insights/strings.json @@ -13,7 +13,8 @@ } }, "abort": { - "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]" + "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", + "unknown": "[%key:common::config_flow::error::unknown%]" }, "error": { "no_integration_selected": "You must select at least one integration to track" diff --git a/tests/components/analytics_insights/test_config_flow.py b/tests/components/analytics_insights/test_config_flow.py index 77264eb2439c6e..6bfd0e798ce96f 100644 --- a/tests/components/analytics_insights/test_config_flow.py +++ b/tests/components/analytics_insights/test_config_flow.py @@ -6,12 +6,12 @@ import pytest from python_homeassistant_analytics import HomeassistantAnalyticsConnectionError -from homeassistant import config_entries from homeassistant.components.analytics_insights.const import ( CONF_TRACKED_CUSTOM_INTEGRATIONS, CONF_TRACKED_INTEGRATIONS, DOMAIN, ) +from homeassistant.config_entries import SOURCE_USER from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType @@ -61,7 +61,7 @@ async def test_form( ) -> None: """Test we get the form.""" result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} + DOMAIN, context={"source": SOURCE_USER} ) assert result["type"] is FlowResultType.FORM @@ -96,7 +96,7 @@ async def test_submitting_empty_form( ) -> None: """Test we can't submit an empty form.""" result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} + DOMAIN, context={"source": SOURCE_USER} ) assert result["type"] is FlowResultType.FORM @@ -128,20 +128,28 @@ async def test_submitting_empty_form( assert len(mock_setup_entry.mock_calls) == 1 +@pytest.mark.parametrize( + ("exception", "reason"), + [ + (HomeassistantAnalyticsConnectionError, "cannot_connect"), + (Exception, "unknown"), + ], +) async def test_form_cannot_connect( - hass: HomeAssistant, mock_analytics_client: AsyncMock + hass: HomeAssistant, + mock_analytics_client: AsyncMock, + exception: Exception, + reason: str, ) -> None: """Test we handle cannot connect error.""" - mock_analytics_client.get_integrations.side_effect = ( - HomeassistantAnalyticsConnectionError - ) + mock_analytics_client.get_integrations.side_effect = exception result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} + DOMAIN, context={"source": SOURCE_USER} ) assert result["type"] is FlowResultType.ABORT - assert result["reason"] == "cannot_connect" + assert result["reason"] == reason async def test_form_already_configured( @@ -159,7 +167,7 @@ async def test_form_already_configured( entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( - DOMAIN, context={"source": config_entries.SOURCE_USER} + DOMAIN, context={"source": SOURCE_USER} ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "single_instance_allowed"