From 133453174083d20ec0a3e9b2985dd02aa35dae30 Mon Sep 17 00:00:00 2001 From: Will Moss Date: Sat, 28 Mar 2026 08:52:42 -0700 Subject: [PATCH] Handle Oauth2 ImplementationUnavailableError in husqvarna_automower (#166633) Co-authored-by: Claude Sonnet 4.6 --- .../husqvarna_automower/__init__.py | 17 ++++++++++++---- .../husqvarna_automower/strings.json | 3 +++ .../husqvarna_automower/test_init.py | 20 +++++++++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/husqvarna_automower/__init__.py b/homeassistant/components/husqvarna_automower/__init__.py index 9ff6b1e06f8..c8260d4d825 100644 --- a/homeassistant/components/husqvarna_automower/__init__.py +++ b/homeassistant/components/husqvarna_automower/__init__.py @@ -11,6 +11,9 @@ from homeassistant.helpers import ( config_entry_oauth2_flow, config_validation as cv, ) +from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, +) from homeassistant.helpers.typing import ConfigType from homeassistant.util import dt as dt_util @@ -42,11 +45,17 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: AutomowerConfigEntry) -> bool: """Set up this integration using UI.""" - implementation = ( - await config_entry_oauth2_flow.async_get_config_entry_implementation( - hass, entry + try: + implementation = ( + await config_entry_oauth2_flow.async_get_config_entry_implementation( + hass, entry + ) ) - ) + except ImplementationUnavailableError as err: + raise ConfigEntryNotReady( + translation_domain=DOMAIN, + translation_key="oauth2_implementation_unavailable", + ) from err session = config_entry_oauth2_flow.OAuth2Session(hass, entry, implementation) api_api = api.AsyncConfigEntryAuth( aiohttp_client.async_get_clientsession(hass), diff --git a/homeassistant/components/husqvarna_automower/strings.json b/homeassistant/components/husqvarna_automower/strings.json index 912c6c3b51a..b40d3666247 100644 --- a/homeassistant/components/husqvarna_automower/strings.json +++ b/homeassistant/components/husqvarna_automower/strings.json @@ -491,6 +491,9 @@ "command_send_failed": { "message": "Failed to send command: {exception}" }, + "oauth2_implementation_unavailable": { + "message": "[%key:common::exceptions::oauth2_implementation_unavailable::message%]" + }, "work_area_not_existing": { "message": "The selected work area does not exist." }, diff --git a/tests/components/husqvarna_automower/test_init.py b/tests/components/husqvarna_automower/test_init.py index e5d26400c37..14fa01fa938 100644 --- a/tests/components/husqvarna_automower/test_init.py +++ b/tests/components/husqvarna_automower/test_init.py @@ -24,6 +24,9 @@ from homeassistant.components.husqvarna_automower.coordinator import SCAN_INTERV from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import device_registry as dr, entity_registry as er +from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, +) from homeassistant.util import dt as dt_util from . import setup_integration @@ -722,3 +725,20 @@ async def test_websocket_watchdog( async_fire_time_changed(hass) await hass.async_block_till_done() assert mock_automower_client.get_status.call_count == 2 + + +async def test_oauth_implementation_not_available( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, +) -> None: + """Test that unavailable OAuth implementation raises ConfigEntryNotReady.""" + mock_config_entry.add_to_hass(hass) + + with patch( + "homeassistant.helpers.config_entry_oauth2_flow.async_get_config_entry_implementation", + side_effect=ImplementationUnavailableError, + ): + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY