diff --git a/homeassistant/components/teslemetry/helpers.py b/homeassistant/components/teslemetry/helpers.py index 2326f68d4fbd..148bb5d846fd 100644 --- a/homeassistant/components/teslemetry/helpers.py +++ b/homeassistant/components/teslemetry/helpers.py @@ -99,10 +99,16 @@ async def handle_command(command: Awaitable[dict[str, Any]]) -> dict[str, Any]: try: result = await command except TeslaFleetError as e: + message = e.message + if isinstance(e.data, dict): + # An error equal to the class key is the machine code that selected it + if (error := e.data.get("error")) == e.key: + error = None + message = e.data.get("error_description") or error or message raise HomeAssistantError( translation_domain=DOMAIN, translation_key="command_exception", - translation_placeholders={"message": e.message}, + translation_placeholders={"message": message}, ) from e except (ClientError, TimeoutError) as e: raise HomeAssistantError( diff --git a/tests/components/teslemetry/test_switch.py b/tests/components/teslemetry/test_switch.py index a2e657c43506..adf4892ff5d2 100644 --- a/tests/components/teslemetry/test_switch.py +++ b/tests/components/teslemetry/test_switch.py @@ -4,7 +4,7 @@ from unittest.mock import AsyncMock, patch import pytest from syrupy.assertion import SnapshotAssertion -from tesla_fleet_api.exceptions import InvalidCommand +from tesla_fleet_api.exceptions import InvalidCommand, InvalidRequest, TeslaFleetError from teslemetry_stream import Signal from homeassistant.components.switch import ( @@ -149,7 +149,49 @@ async def test_switch_command_errors(hass: HomeAssistant, response: dict) -> Non @pytest.mark.usefixtures("entity_registry_enabled_by_default") -async def test_switch_command_exception(hass: HomeAssistant) -> None: +@pytest.mark.parametrize( + ("side_effect", "message"), + [ + pytest.param( + InvalidCommand, + "Command returned exception: The data request or command is unknown.", + id="no_data", + ), + pytest.param( + InvalidRequest( + {"error": "invalid_request", "error_description": "detail from server"} + ), + "Command returned exception: detail from server", + id="error_description", + ), + pytest.param( + InvalidRequest( + { + "response": None, + "error": "vehicle rejected the command", + "error_description": "", + } + ), + "Command returned exception: vehicle rejected the command", + id="error", + ), + pytest.param( + InvalidCommand({"error": "invalid_command", "error_description": ""}), + "Command returned exception: The data request or command is unknown.", + id="error_is_key", + ), + pytest.param( + InvalidRequest({"response": None}), + "Command returned exception: The request body is not valid", + id="no_error_detail", + ), + ], +) +async def test_switch_command_exception( + hass: HomeAssistant, + side_effect: type[TeslaFleetError] | TeslaFleetError, + message: str, +) -> None: """Tests that an energy command SDK exception raises HomeAssistantError.""" await setup_platform(hass, [Platform.SWITCH]) @@ -157,9 +199,9 @@ async def test_switch_command_exception(hass: HomeAssistant) -> None: with ( patch( "tesla_fleet_api.teslemetry.EnergySite.storm_mode", - side_effect=InvalidCommand, + side_effect=side_effect, ), - pytest.raises(HomeAssistantError), + pytest.raises(HomeAssistantError, match=f"^{message}$"), ): await hass.services.async_call( SWITCH_DOMAIN,