From 82d84d7adfbf66089cf924d9482fe33ff0deda3a Mon Sep 17 00:00:00 2001 From: wollew Date: Tue, 23 Dec 2025 13:41:49 +0100 Subject: [PATCH] raise HomeAssistantError when velux gateway reboot fails (#159585) Co-authored-by: Josef Zweck --- homeassistant/components/velux/__init__.py | 17 ++++++-- tests/components/velux/test_init.py | 45 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/velux/__init__.py b/homeassistant/components/velux/__init__.py index 457514c0f3f..c73c3196375 100644 --- a/homeassistant/components/velux/__init__.py +++ b/homeassistant/components/velux/__init__.py @@ -12,7 +12,11 @@ from homeassistant.const import ( EVENT_HOMEASSISTANT_STOP, ) from homeassistant.core import HomeAssistant, ServiceCall -from homeassistant.exceptions import ConfigEntryNotReady, ServiceValidationError +from homeassistant.exceptions import ( + ConfigEntryNotReady, + HomeAssistantError, + ServiceValidationError, +) from homeassistant.helpers import ( config_validation as cv, device_registry as dr, @@ -48,8 +52,15 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # (this is no change to the previous behavior, the alternative would be to reboot all) for entry in hass.config_entries.async_entries(DOMAIN): if entry.state is ConfigEntryState.LOADED: - await entry.runtime_data.reboot_gateway() - return + try: + await entry.runtime_data.reboot_gateway() + except (OSError, PyVLXException) as err: + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="reboot_failed", + ) from err + else: + return raise ServiceValidationError( translation_domain=DOMAIN, diff --git a/tests/components/velux/test_init.py b/tests/components/velux/test_init.py index fc17df0a803..7656b176057 100644 --- a/tests/components/velux/test_init.py +++ b/tests/components/velux/test_init.py @@ -13,9 +13,12 @@ from unittest.mock import patch import pytest from pyvlx.exception import PyVLXException +from homeassistant.components.velux.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.const import Platform from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError, ServiceValidationError +from homeassistant.setup import async_setup_component from tests.common import AsyncMock, ConfigEntry, MockConfigEntry @@ -100,3 +103,45 @@ async def test_unload_does_not_disconnect_if_platform_unload_fails( # Verify disconnect was NOT called since platform unload failed mock_pyvlx.disconnect.assert_not_awaited() + + +@pytest.mark.usefixtures("setup_integration") +async def test_reboot_gateway_service_raises_on_exception( + hass: HomeAssistant, mock_pyvlx: AsyncMock +) -> None: + """Test that reboot_gateway service raises HomeAssistantError on exception.""" + + mock_pyvlx.reboot_gateway.side_effect = OSError("Connection failed") + with pytest.raises(HomeAssistantError, match="Failed to reboot gateway"): + await hass.services.async_call( + "velux", + "reboot_gateway", + blocking=True, + ) + + mock_pyvlx.reboot_gateway.side_effect = PyVLXException("Reboot failed") + with pytest.raises(HomeAssistantError, match="Failed to reboot gateway"): + await hass.services.async_call( + "velux", + "reboot_gateway", + blocking=True, + ) + + +async def test_reboot_gateway_service_raises_validation_error( + hass: HomeAssistant, mock_config_entry: MockConfigEntry +) -> None: + """Test that reboot_gateway service raises ServiceValidationError when no gateway is loaded.""" + # Add the config entry but don't set it up + mock_config_entry.add_to_hass(hass) + + # Set up the velux integration's async_setup to register the service + await async_setup_component(hass, DOMAIN, {}) + await hass.async_block_till_done() + + with pytest.raises(ServiceValidationError, match="No loaded Velux gateway found"): + await hass.services.async_call( + "velux", + "reboot_gateway", + blocking=True, + )