diff --git a/homeassistant/components/samsungtv/bridge.py b/homeassistant/components/samsungtv/bridge.py index e782b1dfcd9..11da83219c7 100644 --- a/homeassistant/components/samsungtv/bridge.py +++ b/homeassistant/components/samsungtv/bridge.py @@ -46,6 +46,7 @@ from homeassistant.const import ( CONF_TOKEN, ) from homeassistant.core import CALLBACK_TYPE, HomeAssistant +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import entity_component from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.device_registry import format_mac @@ -53,6 +54,7 @@ from homeassistant.util import dt as dt_util from .const import ( CONF_SESSION_ID, + DOMAIN, ENCRYPTED_WEBSOCKET_PORT, LEGACY_PORT, LOGGER, @@ -371,9 +373,13 @@ class SamsungTVLegacyBridge(SamsungTVBridge): except (ConnectionClosed, BrokenPipeError): # BrokenPipe can occur when the commands is sent to fast self._remote = None - except (UnhandledResponse, AccessDenied): + except (UnhandledResponse, AccessDenied) as err: # We got a response so it's on. - LOGGER.debug("Failed sending command %s", key, exc_info=True) + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="error_sending_command", + translation_placeholders={"error": repr(err), "host": self.host}, + ) from err except OSError: # Different reasons, e.g. hostname not resolveable pass diff --git a/homeassistant/components/samsungtv/media_player.py b/homeassistant/components/samsungtv/media_player.py index 4fb2e6bd1a2..cc3ca5f142e 100644 --- a/homeassistant/components/samsungtv/media_player.py +++ b/homeassistant/components/samsungtv/media_player.py @@ -29,13 +29,14 @@ from homeassistant.components.media_player import ( MediaType, ) from homeassistant.core import HomeAssistant, callback +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from homeassistant.util.async_ import create_eager_task from .bridge import SamsungTVWSBridge -from .const import CONF_SSDP_RENDERING_CONTROL_LOCATION, LOGGER +from .const import CONF_SSDP_RENDERING_CONTROL_LOCATION, DOMAIN, LOGGER from .coordinator import SamsungTVConfigEntry, SamsungTVDataUpdateCoordinator from .entity import SamsungTVEntity @@ -308,7 +309,12 @@ class SamsungTVDevice(SamsungTVEntity, MediaPlayerEntity): try: await dmr_device.async_set_volume_level(volume) except UpnpActionResponseError as err: - LOGGER.warning("Unable to set volume level on %s: %r", self._host, err) + assert self._host + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="error_set_volume", + translation_placeholders={"error": repr(err), "host": self._host}, + ) from err async def async_volume_up(self) -> None: """Volume up the media player.""" diff --git a/homeassistant/components/samsungtv/strings.json b/homeassistant/components/samsungtv/strings.json index 84e5fded03f..fc3be3fcc19 100644 --- a/homeassistant/components/samsungtv/strings.json +++ b/homeassistant/components/samsungtv/strings.json @@ -68,6 +68,12 @@ "service_unsupported": { "message": "Entity {entity} does not support this action." }, + "error_set_volume": { + "message": "Unable to set volume level on {host}: {error}" + }, + "error_sending_command": { + "message": "Unable to send command to {host}: {error}" + }, "encrypted_mode_auth_failed": { "message": "Token and session ID are required in encrypted mode." }, diff --git a/tests/components/samsungtv/test_media_player.py b/tests/components/samsungtv/test_media_player.py index 0a4587827d1..7dc5c6489d8 100644 --- a/tests/components/samsungtv/test_media_player.py +++ b/tests/components/samsungtv/test_media_player.py @@ -77,7 +77,7 @@ from homeassistant.const import ( STATE_UNAVAILABLE, ) from homeassistant.core import HomeAssistant -from homeassistant.exceptions import ServiceNotSupported +from homeassistant.exceptions import HomeAssistantError, ServiceNotSupported from homeassistant.setup import async_setup_component from . import setup_samsungtv_entry @@ -563,9 +563,11 @@ async def test_send_key_unhandled_response(hass: HomeAssistant, remote: Mock) -> """Testing unhandled response exception.""" await setup_samsungtv_entry(hass, MOCK_CONFIG) remote.control = Mock(side_effect=exceptions.UnhandledResponse("Boom")) - await hass.services.async_call( - MP_DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True - ) + with pytest.raises(HomeAssistantError) as err: + await hass.services.async_call( + MP_DOMAIN, SERVICE_VOLUME_UP, {ATTR_ENTITY_ID: ENTITY_ID}, True + ) + assert err.value.translation_key == "error_sending_command" state = hass.states.get(ENTITY_ID) assert state.state == STATE_ON @@ -1219,9 +1221,7 @@ async def test_websocket_unsupported_remote_control( @pytest.mark.usefixtures("remotews", "rest_api", "upnp_notify_server") -async def test_volume_control_upnp( - hass: HomeAssistant, dmr_device: Mock, caplog: pytest.LogCaptureFixture -) -> None: +async def test_volume_control_upnp(hass: HomeAssistant, dmr_device: Mock) -> None: """Test for Upnp volume control.""" await setup_samsungtv_entry(hass, MOCK_ENTRY_WS) @@ -1237,21 +1237,21 @@ async def test_volume_control_upnp( True, ) dmr_device.async_set_volume_level.assert_called_once_with(0.5) - assert "Unable to set volume level on" not in caplog.text # Upnp action failed dmr_device.async_set_volume_level.reset_mock() dmr_device.async_set_volume_level.side_effect = UpnpActionResponseError( status=500, error_code=501, error_desc="Action Failed" ) - await hass.services.async_call( - MP_DOMAIN, - SERVICE_VOLUME_SET, - {ATTR_ENTITY_ID: ENTITY_ID, ATTR_MEDIA_VOLUME_LEVEL: 0.6}, - True, - ) + with pytest.raises(HomeAssistantError) as err: + await hass.services.async_call( + MP_DOMAIN, + SERVICE_VOLUME_SET, + {ATTR_ENTITY_ID: ENTITY_ID, ATTR_MEDIA_VOLUME_LEVEL: 0.6}, + True, + ) + assert err.value.translation_key == "error_set_volume" dmr_device.async_set_volume_level.assert_called_once_with(0.6) - assert "Unable to set volume level on" in caplog.text @pytest.mark.usefixtures("remotews", "rest_api")