mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 09:23:17 -04:00
Fix uncaught Duco diagnostics client errors (#173191)
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
from dataclasses import asdict
|
||||
from typing import Any
|
||||
|
||||
from duco_connectivity.exceptions import DucoConnectionError
|
||||
from duco_connectivity.exceptions import DucoConnectionError, DucoError
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.const import CONF_HOST
|
||||
@@ -52,6 +52,12 @@ async def async_get_config_entry_diagnostics(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="connection_error",
|
||||
) from err
|
||||
except DucoError as err:
|
||||
raise HomeAssistantError(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="api_error",
|
||||
translation_placeholders={"error": repr(err)},
|
||||
) from err
|
||||
|
||||
api_info: dict[str, Any] = {"public_api_version": api_info_obj.public_api_version}
|
||||
if api_info_obj.reported_api_version is not None:
|
||||
|
||||
@@ -4,7 +4,12 @@ from dataclasses import replace
|
||||
from http import HTTPStatus
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from duco_connectivity import ApiInfo, DucoConnectionError
|
||||
from duco_connectivity import ApiInfo
|
||||
from duco_connectivity.exceptions import (
|
||||
DucoConnectionError,
|
||||
DucoError,
|
||||
DucoResponseError,
|
||||
)
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
@@ -16,6 +21,29 @@ from tests.common import MockConfigEntry
|
||||
from tests.components.diagnostics import get_diagnostics_for_config_entry
|
||||
from tests.typing import ClientSessionGenerator
|
||||
|
||||
CLIENT_ERROR_CASES = [
|
||||
pytest.param(
|
||||
"async_get_api_info",
|
||||
DucoConnectionError("Server disconnected"),
|
||||
id="api-info-connection-error",
|
||||
),
|
||||
pytest.param(
|
||||
"async_get_lan_info",
|
||||
DucoConnectionError("Server disconnected"),
|
||||
id="lan-info-connection-error",
|
||||
),
|
||||
pytest.param(
|
||||
"async_get_diagnostics",
|
||||
DucoResponseError(500, "/info", "bad response"),
|
||||
id="diagnostics-response-error",
|
||||
),
|
||||
pytest.param(
|
||||
"async_get_write_requests_remaining",
|
||||
DucoResponseError(500, "/info", "bad response"),
|
||||
id="write-budget-response-error",
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_diagnostics(
|
||||
@@ -34,25 +62,19 @@ async def test_diagnostics(
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
@pytest.mark.parametrize(
|
||||
"failing_method",
|
||||
[
|
||||
"async_get_api_info",
|
||||
"async_get_lan_info",
|
||||
"async_get_diagnostics",
|
||||
"async_get_write_requests_remaining",
|
||||
],
|
||||
("failing_method", "raised_error"),
|
||||
CLIENT_ERROR_CASES,
|
||||
)
|
||||
async def test_diagnostics_connection_error(
|
||||
async def test_diagnostics_client_error(
|
||||
hass: HomeAssistant,
|
||||
hass_client: ClientSessionGenerator,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_duco_client: AsyncMock,
|
||||
failing_method: str,
|
||||
raised_error: DucoError,
|
||||
) -> None:
|
||||
"""Test that a connection error during diagnostics returns a 500 response."""
|
||||
getattr(mock_duco_client, failing_method).side_effect = DucoConnectionError(
|
||||
"Server disconnected"
|
||||
)
|
||||
"""Test that client errors during diagnostics return a 500 response."""
|
||||
getattr(mock_duco_client, failing_method).side_effect = raised_error
|
||||
assert await async_setup_component(hass, DIAGNOSTICS_DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
client = await hass_client()
|
||||
@@ -70,7 +92,7 @@ async def test_diagnostics_without_optional_software_version(
|
||||
) -> None:
|
||||
"""Test that an optional software version is omitted from diagnostics."""
|
||||
# BoardInfo is a frozen dataclass, so the mock must be updated before
|
||||
# integration setup — the coordinator stores board_info during async_setup.
|
||||
# integration setup - the coordinator stores board_info during async_setup.
|
||||
mock_duco_client.async_get_board_info.return_value = replace(
|
||||
mock_duco_client.async_get_board_info.return_value,
|
||||
software_version=None,
|
||||
|
||||
Reference in New Issue
Block a user