From 6cfe6ed54364cedc6e9c0bfb447dd04c439bf5b0 Mon Sep 17 00:00:00 2001 From: Will Moss Date: Sun, 9 Nov 2025 12:47:28 -0800 Subject: [PATCH] Improved error handling for oauth2 configuration in spotify integration (#156201) --- homeassistant/components/spotify/__init__.py | 9 +++++++- homeassistant/components/spotify/strings.json | 5 ++++ tests/components/spotify/test_init.py | 23 ++++++++++++++++++- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/spotify/__init__.py b/homeassistant/components/spotify/__init__.py index 1c4ea961ce3..aee7a1a62df 100644 --- a/homeassistant/components/spotify/__init__.py +++ b/homeassistant/components/spotify/__init__.py @@ -13,6 +13,7 @@ from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, OAuth2Session, async_get_config_entry_implementation, ) @@ -41,7 +42,13 @@ __all__ = [ async def async_setup_entry(hass: HomeAssistant, entry: SpotifyConfigEntry) -> bool: """Set up Spotify from a config entry.""" - implementation = await async_get_config_entry_implementation(hass, entry) + try: + implementation = await async_get_config_entry_implementation(hass, entry) + except ImplementationUnavailableError as err: + raise ConfigEntryNotReady( + translation_domain=DOMAIN, + translation_key="oauth2_implementation_unavailable", + ) from err session = OAuth2Session(hass, entry, implementation) try: diff --git a/homeassistant/components/spotify/strings.json b/homeassistant/components/spotify/strings.json index 3cbebf4c5b6..a63af62309b 100644 --- a/homeassistant/components/spotify/strings.json +++ b/homeassistant/components/spotify/strings.json @@ -32,6 +32,11 @@ } } }, + "exceptions": { + "oauth2_implementation_unavailable": { + "message": "OAuth2 implementation unavailable, will retry" + } + }, "system_health": { "info": { "api_endpoint_reachable": "Spotify API endpoint reachable" diff --git a/tests/components/spotify/test_init.py b/tests/components/spotify/test_init.py index 21129d20c07..65dca5fa7ae 100644 --- a/tests/components/spotify/test_init.py +++ b/tests/components/spotify/test_init.py @@ -1,12 +1,15 @@ """Tests for the Spotify initialization.""" -from unittest.mock import MagicMock +from unittest.mock import MagicMock, patch import pytest from spotifyaio import SpotifyConnectionError from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant +from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, +) from . import setup_integration @@ -48,3 +51,21 @@ async def test_setup_with_required_calls_failing( mock_config_entry.add_to_hass(hass) assert not await hass.config_entries.async_setup(mock_config_entry.entry_id) + + +@pytest.mark.usefixtures("setup_credentials") +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.components.spotify.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