From 15e13de2a6161cd5438d049e5f7ff1bc24019040 Mon Sep 17 00:00:00 2001 From: Will Moss Date: Sat, 28 Mar 2026 08:51:48 -0700 Subject: [PATCH] Handle Oauth2 ImplementationUnavailableError in lyric (#166655) Co-authored-by: Claude Sonnet 4.6 --- homeassistant/components/lyric/__init__.py | 15 +++++--- homeassistant/components/lyric/strings.json | 5 +++ tests/components/lyric/test_init.py | 40 +++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 tests/components/lyric/test_init.py diff --git a/homeassistant/components/lyric/__init__.py b/homeassistant/components/lyric/__init__.py index c221b03a891..95fb559491d 100644 --- a/homeassistant/components/lyric/__init__.py +++ b/homeassistant/components/lyric/__init__.py @@ -6,6 +6,7 @@ from aiolyric import Lyric from homeassistant.const import Platform from homeassistant.core import HomeAssistant +from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers import ( aiohttp_client, config_entry_oauth2_flow, @@ -27,11 +28,17 @@ PLATFORMS = [Platform.CLIMATE, Platform.SENSOR] async def async_setup_entry(hass: HomeAssistant, entry: LyricConfigEntry) -> bool: """Set up Honeywell Lyric from a config entry.""" - 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 config_entry_oauth2_flow.ImplementationUnavailableError as err: + raise ConfigEntryNotReady( + translation_domain=DOMAIN, + translation_key="oauth2_implementation_unavailable", + ) from err if not isinstance(implementation, LyricLocalOAuth2Implementation): raise TypeError("Unexpected auth implementation; can't find oauth client id") diff --git a/homeassistant/components/lyric/strings.json b/homeassistant/components/lyric/strings.json index c3bace886d4..51f1cff5269 100644 --- a/homeassistant/components/lyric/strings.json +++ b/homeassistant/components/lyric/strings.json @@ -64,6 +64,11 @@ } } }, + "exceptions": { + "oauth2_implementation_unavailable": { + "message": "[%key:common::exceptions::oauth2_implementation_unavailable::message%]" + } + }, "services": { "set_hold_time": { "description": "Sets the time period to keep the temperature and override the schedule.", diff --git a/tests/components/lyric/test_init.py b/tests/components/lyric/test_init.py new file mode 100644 index 00000000000..43316079fe1 --- /dev/null +++ b/tests/components/lyric/test_init.py @@ -0,0 +1,40 @@ +"""Tests for the Honeywell Lyric integration.""" + +from unittest.mock import patch + +from homeassistant.components.lyric.const import DOMAIN +from homeassistant.config_entries import ConfigEntryState +from homeassistant.core import HomeAssistant +from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, +) + +from tests.common import MockConfigEntry + + +async def test_oauth_implementation_not_available( + hass: HomeAssistant, +) -> None: + """Test that unavailable OAuth implementation raises ConfigEntryNotReady.""" + entry = MockConfigEntry( + domain=DOMAIN, + data={ + "auth_implementation": DOMAIN, + "token": { + "access_token": "mock-access-token", + "refresh_token": "mock-refresh-token", + "expires_at": 9999999999, + "token_type": "Bearer", + }, + }, + ) + 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(entry.entry_id) + await hass.async_block_till_done() + + assert entry.state is ConfigEntryState.SETUP_RETRY