From 603d4bcf871cd90ec8700d0ea47e89f3d0de95d5 Mon Sep 17 00:00:00 2001 From: Will Moss Date: Tue, 11 Nov 2025 13:23:56 -0800 Subject: [PATCH] Improved error handling for oauth2 configuration in weheat integration (#156217) --- homeassistant/components/weheat/__init__.py | 11 ++++++++-- homeassistant/components/weheat/strings.json | 5 +++++ tests/components/weheat/test_init.py | 21 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/homeassistant/components/weheat/__init__.py b/homeassistant/components/weheat/__init__.py index 15935f3e418..2e3df341881 100644 --- a/homeassistant/components/weheat/__init__.py +++ b/homeassistant/components/weheat/__init__.py @@ -14,11 +14,12 @@ 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, ) -from .const import API_URL, LOGGER +from .const import API_URL, DOMAIN, LOGGER from .coordinator import ( HeatPumpInfo, WeheatConfigEntry, @@ -32,7 +33,13 @@ PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.SENSOR] async def async_setup_entry(hass: HomeAssistant, entry: WeheatConfigEntry) -> bool: """Set up Weheat 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) diff --git a/homeassistant/components/weheat/strings.json b/homeassistant/components/weheat/strings.json index f86bc9baa34..908abc8b6ae 100644 --- a/homeassistant/components/weheat/strings.json +++ b/homeassistant/components/weheat/strings.json @@ -124,5 +124,10 @@ "name": "Water outlet temperature" } } + }, + "exceptions": { + "oauth2_implementation_unavailable": { + "message": "[%key:common::exceptions::oauth2_implementation_unavailable::message%]" + } } } diff --git a/tests/components/weheat/test_init.py b/tests/components/weheat/test_init.py index af5e2b8411b..8ce41ab43e7 100644 --- a/tests/components/weheat/test_init.py +++ b/tests/components/weheat/test_init.py @@ -9,6 +9,9 @@ from weheat.abstractions.discovery import HeatPumpDiscovery from homeassistant.components.weheat import UnauthorizedException from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant +from homeassistant.helpers.config_entry_oauth2_flow import ( + ImplementationUnavailableError, +) from . import setup_integration @@ -83,3 +86,21 @@ async def test_setup_fail_discover( await setup_integration(hass, mock_config_entry) assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR + + +@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.weheat.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