Raise exceptions in HEOS custom actions (#136546)

This commit is contained in:
Andrew Sayre
2025-01-28 07:08:40 -06:00
committed by GitHub
parent 79de8114d3
commit c4f8de8fd9
3 changed files with 43 additions and 35 deletions

View File

@@ -7,7 +7,7 @@ import voluptuous as vol
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import config_validation as cv, issue_registry as ir from homeassistant.helpers import config_validation as cv, issue_registry as ir
from .const import ( from .const import (
@@ -46,7 +46,6 @@ def register(hass: HomeAssistant):
def _get_controller(hass: HomeAssistant) -> Heos: def _get_controller(hass: HomeAssistant) -> Heos:
"""Get the HEOS controller instance.""" """Get the HEOS controller instance."""
_LOGGER.warning( _LOGGER.warning(
"Actions 'heos.sign_in' and 'heos.sign_out' are deprecated and will be removed in the 2025.8.0 release" "Actions 'heos.sign_in' and 'heos.sign_out' are deprecated and will be removed in the 2025.8.0 release"
) )
@@ -79,16 +78,25 @@ async def _sign_in_handler(service: ServiceCall) -> None:
try: try:
await controller.sign_in(username, password) await controller.sign_in(username, password)
except CommandAuthenticationError as err: except CommandAuthenticationError as err:
_LOGGER.error("Sign in failed: %s", err) raise ServiceValidationError(
translation_domain=DOMAIN, translation_key="sign_in_auth_error"
) from err
except HeosError as err: except HeosError as err:
_LOGGER.error("Unable to sign in: %s", err) raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="sign_in_error",
translation_placeholders={"error": str(err)},
) from err
async def _sign_out_handler(service: ServiceCall) -> None: async def _sign_out_handler(service: ServiceCall) -> None:
"""Sign out of the HEOS account.""" """Sign out of the HEOS account."""
controller = _get_controller(service.hass) controller = _get_controller(service.hass)
try: try:
await controller.sign_out() await controller.sign_out()
except HeosError as err: except HeosError as err:
_LOGGER.error("Unable to sign out: %s", err) raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="sign_out_error",
translation_placeholders={"error": str(err)},
) from err

View File

@@ -100,6 +100,15 @@
"integration_not_loaded": { "integration_not_loaded": {
"message": "The HEOS integration is not loaded" "message": "The HEOS integration is not loaded"
}, },
"sign_in_auth_error": {
"message": "Failed to sign in: Invalid username and/or password"
},
"sign_in_error": {
"message": "Unable to sign in: {error}"
},
"sign_out_error": {
"message": "Unable to sign out: {error}"
},
"not_heos_media_player": { "not_heos_media_player": {
"message": "Entity {entity_id} is not a HEOS media player entity" "message": "Entity {entity_id} is not a HEOS media player entity"
}, },

View File

@@ -11,7 +11,7 @@ from homeassistant.components.heos.const import (
SERVICE_SIGN_OUT, SERVICE_SIGN_OUT,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
@@ -34,10 +34,7 @@ async def test_sign_in(
async def test_sign_in_failed( async def test_sign_in_failed(
hass: HomeAssistant, hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
config_entry: MockConfigEntry,
controller: Heos,
caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
"""Test sign-in service logs error when not connected.""" """Test sign-in service logs error when not connected."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@@ -47,6 +44,7 @@ async def test_sign_in_failed(
"", "Invalid credentials", 6 "", "Invalid credentials", 6
) )
with pytest.raises(ServiceValidationError):
await hass.services.async_call( await hass.services.async_call(
DOMAIN, DOMAIN,
SERVICE_SIGN_IN, SERVICE_SIGN_IN,
@@ -55,14 +53,10 @@ async def test_sign_in_failed(
) )
controller.sign_in.assert_called_once_with("test@test.com", "password") controller.sign_in.assert_called_once_with("test@test.com", "password")
assert "Sign in failed: Invalid credentials (6)" in caplog.text
async def test_sign_in_unknown_error( async def test_sign_in_unknown_error(
hass: HomeAssistant, hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
config_entry: MockConfigEntry,
controller: Heos,
caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
"""Test sign-in service logs error for failure.""" """Test sign-in service logs error for failure."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
@@ -70,6 +64,7 @@ async def test_sign_in_unknown_error(
controller.sign_in.side_effect = HeosError() controller.sign_in.side_effect = HeosError()
with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
DOMAIN, DOMAIN,
SERVICE_SIGN_IN, SERVICE_SIGN_IN,
@@ -78,7 +73,6 @@ async def test_sign_in_unknown_error(
) )
controller.sign_in.assert_called_once_with("test@test.com", "password") controller.sign_in.assert_called_once_with("test@test.com", "password")
assert "Unable to sign in" in caplog.text
async def test_sign_in_not_loaded_raises( async def test_sign_in_not_loaded_raises(
@@ -123,17 +117,14 @@ async def test_sign_out_not_loaded_raises(
async def test_sign_out_unknown_error( async def test_sign_out_unknown_error(
hass: HomeAssistant, hass: HomeAssistant, config_entry: MockConfigEntry, controller: Heos
config_entry: MockConfigEntry,
controller: Heos,
caplog: pytest.LogCaptureFixture,
) -> None: ) -> None:
"""Test the sign-out service.""" """Test the sign-out service."""
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id) assert await hass.config_entries.async_setup(config_entry.entry_id)
controller.sign_out.side_effect = HeosError() controller.sign_out.side_effect = HeosError()
with pytest.raises(HomeAssistantError):
await hass.services.async_call(DOMAIN, SERVICE_SIGN_OUT, {}, blocking=True) await hass.services.async_call(DOMAIN, SERVICE_SIGN_OUT, {}, blocking=True)
assert controller.sign_out.call_count == 1 assert controller.sign_out.call_count == 1
assert "Unable to sign out" in caplog.text