From da805874298059bf5af30939129dc407aa295fb2 Mon Sep 17 00:00:00 2001 From: Brett Adams Date: Wed, 30 Sep 2026 01:47:14 +1000 Subject: [PATCH] Translate Teslemetry command connection errors (#183457) --- .../components/teslemetry/helpers.py | 6 +++++ .../components/teslemetry/strings.json | 3 +++ tests/components/teslemetry/test_lock.py | 22 +++++++++++++++---- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/homeassistant/components/teslemetry/helpers.py b/homeassistant/components/teslemetry/helpers.py index b8d0840dd158..2326f68d4fbd 100644 --- a/homeassistant/components/teslemetry/helpers.py +++ b/homeassistant/components/teslemetry/helpers.py @@ -4,6 +4,7 @@ import asyncio from collections.abc import Awaitable from typing import Any, cast +from aiohttp import ClientError from aiopowerwall import PowerwallAuthenticationError, PowerwallClient from tesla_fleet_api.exceptions import TeslaFleetError from tesla_fleet_api.tesla import EnergySiteRouter @@ -103,6 +104,11 @@ async def handle_command(command: Awaitable[dict[str, Any]]) -> dict[str, Any]: translation_key="command_exception", translation_placeholders={"message": e.message}, ) from e + except (ClientError, TimeoutError) as e: + raise HomeAssistantError( + translation_domain=DOMAIN, + translation_key="command_connection_error", + ) from e LOGGER.debug("Command result: %s", result) return result diff --git a/homeassistant/components/teslemetry/strings.json b/homeassistant/components/teslemetry/strings.json index a6d059707cdc..b6c10f359195 100644 --- a/homeassistant/components/teslemetry/strings.json +++ b/homeassistant/components/teslemetry/strings.json @@ -1232,6 +1232,9 @@ "auth_failed_subscription_required": { "message": "Teslemetry subscription required" }, + "command_connection_error": { + "message": "Unable to connect to Teslemetry" + }, "command_error": { "message": "Command returned error: {error}" }, diff --git a/tests/components/teslemetry/test_lock.py b/tests/components/teslemetry/test_lock.py index 57664665de2e..f169b592d084 100644 --- a/tests/components/teslemetry/test_lock.py +++ b/tests/components/teslemetry/test_lock.py @@ -2,6 +2,7 @@ from unittest.mock import AsyncMock, patch +from aiohttp import ClientConnectionError import pytest from syrupy.assertion import SnapshotAssertion from tesla_fleet_api.exceptions import InvalidCommand @@ -131,17 +132,29 @@ async def test_lock_command_errors(hass: HomeAssistant, response: dict) -> None: ) -async def test_lock_command_exception(hass: HomeAssistant) -> None: - """Tests that a command SDK exception raises HomeAssistantError.""" +@pytest.mark.parametrize( + ("side_effect", "translation_key"), + [ + pytest.param(InvalidCommand, "command_exception", id="fleet_error"), + pytest.param( + ClientConnectionError, "command_connection_error", id="client_error" + ), + pytest.param(TimeoutError, "command_connection_error", id="timeout"), + ], +) +async def test_lock_command_exception( + hass: HomeAssistant, side_effect: type[BaseException], translation_key: str +) -> None: + """Tests that a command exception raises a translated HomeAssistantError.""" await setup_platform(hass, [Platform.LOCK]) with ( patch( "tesla_fleet_api.teslemetry.Vehicle.door_lock", - side_effect=InvalidCommand, + side_effect=side_effect, ), - pytest.raises(HomeAssistantError), + pytest.raises(HomeAssistantError) as exc_info, ): await hass.services.async_call( LOCK_DOMAIN, @@ -149,6 +162,7 @@ async def test_lock_command_exception(hass: HomeAssistant) -> None: {ATTR_ENTITY_ID: "lock.test_lock"}, blocking=True, ) + assert exc_info.value.translation_key == translation_key async def test_lock_streaming(