From 9d60a19440fd0ed64db5eb55a067594ee943cdad Mon Sep 17 00:00:00 2001 From: Will Moss Date: Mon, 10 Nov 2025 04:17:48 -0800 Subject: [PATCH] Improved error handling for oauth2 configuration in volvo integration (#156215) --- homeassistant/components/volvo/__init__.py | 9 ++++++++- homeassistant/components/volvo/strings.json | 3 +++ tests/components/volvo/test_init.py | 22 ++++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/volvo/__init__.py b/homeassistant/components/volvo/__init__.py index 8f380f4dbd74..a4f1365274f2 100644 --- a/homeassistant/components/volvo/__init__.py +++ b/homeassistant/components/volvo/__init__.py @@ -16,6 +16,7 @@ from homeassistant.exceptions import ( ) from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, OAuth2Session, async_get_config_entry_implementation, ) @@ -65,7 +66,13 @@ async def async_unload_entry(hass: HomeAssistant, entry: VolvoConfigEntry) -> bo async def _async_auth_and_create_api( hass: HomeAssistant, entry: VolvoConfigEntry ) -> VolvoCarsApi: - 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 oauth_session = OAuth2Session(hass, entry, implementation) web_session = async_get_clientsession(hass) auth = VolvoAuth(web_session, oauth_session) diff --git a/homeassistant/components/volvo/strings.json b/homeassistant/components/volvo/strings.json index b1dccf97dacd..65baec78e81f 100644 --- a/homeassistant/components/volvo/strings.json +++ b/homeassistant/components/volvo/strings.json @@ -362,6 +362,9 @@ "no_vehicle": { "message": "Unable to retrieve vehicle details." }, + "oauth2_implementation_unavailable": { + "message": "OAuth2 implementation unavailable, will retry" + }, "unauthorized": { "message": "Authentication failed. {message}" }, diff --git a/tests/components/volvo/test_init.py b/tests/components/volvo/test_init.py index e4e08c22f39f..6c1bfa8cfa97 100644 --- a/tests/components/volvo/test_init.py +++ b/tests/components/volvo/test_init.py @@ -2,7 +2,7 @@ from collections.abc import Awaitable, Callable from http import HTTPStatus -from unittest.mock import AsyncMock +from unittest.mock import AsyncMock, patch import pytest from volvocarsapi.api import VolvoCarsApi @@ -13,6 +13,9 @@ from homeassistant.components.volvo.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.const import CONF_TOKEN from homeassistant.core import HomeAssistant +from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, +) from . import configure_mock from .const import MOCK_ACCESS_TOKEN, SERVER_TOKEN_RESPONSE @@ -132,3 +135,20 @@ async def test_vehicle_auth_failure( configure_mock(mock_method, return_value=None, side_effect=VolvoAuthException()) assert not await setup_integration() assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR + + +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.volvo.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