mirror of
https://github.com/home-assistant/core.git
synced 2026-08-07 13:55:32 +01:00
Improve Sonos error message on UPNP 800 - music service unavailable (#176167)
This commit is contained in:
@@ -16,7 +16,7 @@ from homeassistant.core import CALLBACK_TYPE
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers.dispatcher import dispatcher_send
|
||||
|
||||
from .const import SONOS_SPEAKER_ACTIVITY
|
||||
from .const import DOMAIN, SONOS_SPEAKER_ACTIVITY
|
||||
from .exception import SonosUpdateError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@@ -30,6 +30,8 @@ if TYPE_CHECKING:
|
||||
UID_PREFIX = "RINCON_"
|
||||
UID_POSTFIX = "01400"
|
||||
|
||||
UPNP_ERROR_COMMAND_FAILED = "800"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
type _SonosEntitiesType = (
|
||||
@@ -76,8 +78,24 @@ def soco_error[_T: _SonosEntitiesType, **_P, _R](
|
||||
if (target := _find_target_identifier(self, args_soco)) is None:
|
||||
raise RuntimeError("Unexpected use of soco_error") from err
|
||||
|
||||
message = f"Error calling {function} on {target}: {err}"
|
||||
raise SonosUpdateError(message) from err
|
||||
translation_key = "call_failed"
|
||||
placeholders = {
|
||||
"target": target,
|
||||
"error": str(err),
|
||||
}
|
||||
|
||||
if error_code is not None:
|
||||
translation_key = "upnp_call_failed"
|
||||
placeholders["error_code"] = str(error_code)
|
||||
|
||||
if str(error_code) == UPNP_ERROR_COMMAND_FAILED:
|
||||
translation_key = "upnp_call_failed_music_service_unavailable"
|
||||
|
||||
raise SonosUpdateError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key=translation_key,
|
||||
translation_placeholders=placeholders,
|
||||
) from err
|
||||
|
||||
dispatch_soco = args_soco or self.soco # type: ignore[union-attr]
|
||||
dispatcher_send(
|
||||
|
||||
@@ -109,6 +109,9 @@
|
||||
"announce_media_error": {
|
||||
"message": "Announcing clip {media_id} failed {response}"
|
||||
},
|
||||
"call_failed": {
|
||||
"message": "Error on {target}: {error}"
|
||||
},
|
||||
"entity_not_found": {
|
||||
"message": "Entity {entity_id} not found."
|
||||
},
|
||||
@@ -141,6 +144,12 @@
|
||||
},
|
||||
"toggle_failed": {
|
||||
"message": "Could not toggle {entity_id}."
|
||||
},
|
||||
"upnp_call_failed": {
|
||||
"message": "Error on {target} (UPnP error code {error_code}): {error}"
|
||||
},
|
||||
"upnp_call_failed_music_service_unavailable": {
|
||||
"message": "Error on {target} (UPnP error code {error_code}): {error}. This may indicate the selected music service is not available on the speaker."
|
||||
}
|
||||
},
|
||||
"issues": {
|
||||
|
||||
@@ -13,6 +13,7 @@ from soco.data_structures import (
|
||||
DidlPlaylistContainer,
|
||||
SearchResult,
|
||||
)
|
||||
from soco.exceptions import SoCoUPnPException
|
||||
from sonos_websocket.exception import SonosWebsocketError
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
@@ -326,6 +327,69 @@ async def test_play_media_library_content_error(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("error", "translation_key", "translation_placeholders"),
|
||||
[
|
||||
pytest.param(
|
||||
OSError("Network down"),
|
||||
"call_failed",
|
||||
{
|
||||
"target": "media_player.zone_a",
|
||||
"error": "Network down",
|
||||
},
|
||||
id="generic-error",
|
||||
),
|
||||
pytest.param(
|
||||
SoCoUPnPException("UPnP Error 701 received", "701", ""),
|
||||
"upnp_call_failed",
|
||||
{
|
||||
"target": "media_player.zone_a",
|
||||
"error": "UPnP Error 701 received",
|
||||
"error_code": "701",
|
||||
},
|
||||
id="upnp-error",
|
||||
),
|
||||
pytest.param(
|
||||
SoCoUPnPException("UPnP Error 800 received", "800", ""),
|
||||
"upnp_call_failed_music_service_unavailable",
|
||||
{
|
||||
"target": "media_player.zone_a",
|
||||
"error": "UPnP Error 800 received",
|
||||
"error_code": "800",
|
||||
},
|
||||
id="upnp-error-800-music-service-unavailable",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_play_media_error_translation(
|
||||
hass: HomeAssistant,
|
||||
soco_factory: SoCoMockFactory,
|
||||
async_autosetup_sonos,
|
||||
error: Exception,
|
||||
translation_key: str,
|
||||
translation_placeholders: dict[str, str],
|
||||
) -> None:
|
||||
"""Test play_media surfaces translated error details for failures."""
|
||||
soco_mock = soco_factory.mock_list.get("192.168.42.2")
|
||||
soco_mock.play_uri.side_effect = error
|
||||
|
||||
with pytest.raises(HomeAssistantError) as err:
|
||||
await hass.services.async_call(
|
||||
MP_DOMAIN,
|
||||
SERVICE_PLAY_MEDIA,
|
||||
{
|
||||
ATTR_ENTITY_ID: "media_player.zone_a",
|
||||
ATTR_MEDIA_CONTENT_TYPE: "track",
|
||||
ATTR_MEDIA_CONTENT_ID: _track_url,
|
||||
ATTR_MEDIA_ENQUEUE: MediaPlayerEnqueue.REPLACE,
|
||||
},
|
||||
blocking=True,
|
||||
)
|
||||
|
||||
assert err.value.translation_key == translation_key
|
||||
assert err.value.translation_placeholders == translation_placeholders
|
||||
|
||||
|
||||
_track_url = "S://192.168.42.100/music/iTunes/The%20Beatles/A%20Hard%20Day%2fs%I%20Should%20Have%20Known%20Better.mp3"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user