diff --git a/homeassistant/components/ondilo_ico/coordinator.py b/homeassistant/components/ondilo_ico/coordinator.py
index 9a98ce0037e..bc092ad0b9a 100644
--- a/homeassistant/components/ondilo_ico/coordinator.py
+++ b/homeassistant/components/ondilo_ico/coordinator.py
@@ -42,9 +42,7 @@ class OndiloIcoCoordinator(DataUpdateCoordinator[dict[str, OndiloIcoData]]):
"""Fetch data from API endpoint."""
try:
return await self.hass.async_add_executor_job(self._update_data)
-
except OndiloError as err:
- _LOGGER.exception("Error getting pools")
raise UpdateFailed(f"Error communicating with API: {err}") from err
def _update_data(self) -> dict[str, OndiloIcoData]:
@@ -52,23 +50,28 @@ class OndiloIcoCoordinator(DataUpdateCoordinator[dict[str, OndiloIcoData]]):
res = {}
pools = self.api.get_pools()
_LOGGER.debug("Pools: %s", pools)
+ error: OndiloError | None = None
for pool in pools:
+ pool_id = pool["id"]
try:
- ico = self.api.get_ICO_details(pool["id"])
+ ico = self.api.get_ICO_details(pool_id)
if not ico:
_LOGGER.debug(
- "The pool id %s does not have any ICO attached", pool["id"]
+ "The pool id %s does not have any ICO attached", pool_id
)
continue
- sensors = self.api.get_last_pool_measures(pool["id"])
- except OndiloError:
- _LOGGER.exception("Error communicating with API for %s", pool["id"])
+ sensors = self.api.get_last_pool_measures(pool_id)
+ except OndiloError as err:
+ error = err
+ _LOGGER.debug("Error communicating with API for %s: %s", pool_id, err)
continue
- res[pool["id"]] = OndiloIcoData(
+ res[pool_id] = OndiloIcoData(
ico=ico,
pool=pool,
sensors={sensor["data_type"]: sensor["value"] for sensor in sensors},
)
if not res:
+ if error:
+ raise UpdateFailed(f"Error communicating with API: {error}") from error
raise UpdateFailed("No data available")
return res
diff --git a/tests/components/ondilo_ico/test_init.py b/tests/components/ondilo_ico/test_init.py
index 707022e9145..67f68f27b3e 100644
--- a/tests/components/ondilo_ico/test_init.py
+++ b/tests/components/ondilo_ico/test_init.py
@@ -3,6 +3,8 @@
from typing import Any
from unittest.mock import MagicMock
+from ondilo import OndiloError
+import pytest
from syrupy import SnapshotAssertion
from homeassistant.config_entries import ConfigEntryState
@@ -35,6 +37,29 @@ async def test_devices(
assert device_entry == snapshot(name=f"{identifier[0]}-{identifier[1]}")
+async def test_get_pools_error(
+ hass: HomeAssistant,
+ mock_ondilo_client: MagicMock,
+ config_entry: MockConfigEntry,
+) -> None:
+ """Test get pools errors."""
+ mock_ondilo_client.get_pools.side_effect = OndiloError(
+ 502,
+ (
+ "
502 Bad Gateway "
+ " 502 Bad Gateway
"
+ ),
+ )
+ await setup_integration(hass, config_entry, mock_ondilo_client)
+
+ # No sensor should be created
+ assert not hass.states.async_all()
+ # We should not have tried to retrieve pool measures
+ assert mock_ondilo_client.get_ICO_details.call_count == 0
+ assert mock_ondilo_client.get_last_pool_measures.call_count == 0
+ assert config_entry.state is ConfigEntryState.SETUP_RETRY
+
+
async def test_init_with_no_ico_attached(
hass: HomeAssistant,
mock_ondilo_client: MagicMock,
@@ -53,3 +78,77 @@ async def test_init_with_no_ico_attached(
# We should not have tried to retrieve pool measures
mock_ondilo_client.get_last_pool_measures.assert_not_called()
assert config_entry.state is ConfigEntryState.SETUP_RETRY
+
+
+@pytest.mark.parametrize("api", ["get_ICO_details", "get_last_pool_measures"])
+async def test_details_error_all_pools(
+ hass: HomeAssistant,
+ mock_ondilo_client: MagicMock,
+ device_registry: dr.DeviceRegistry,
+ config_entry: MockConfigEntry,
+ pool1: dict[str, Any],
+ api: str,
+) -> None:
+ """Test details and measures error for all pools."""
+ mock_ondilo_client.get_pools.return_value = pool1
+ client_api = getattr(mock_ondilo_client, api)
+ client_api.side_effect = OndiloError(400, "error")
+
+ await setup_integration(hass, config_entry, mock_ondilo_client)
+
+ device_entries = dr.async_entries_for_config_entry(
+ device_registry, config_entry.entry_id
+ )
+
+ assert not device_entries
+ assert config_entry.state is ConfigEntryState.SETUP_RETRY
+
+
+async def test_details_error_one_pool(
+ hass: HomeAssistant,
+ mock_ondilo_client: MagicMock,
+ device_registry: dr.DeviceRegistry,
+ config_entry: MockConfigEntry,
+ ico_details2: dict[str, Any],
+) -> None:
+ """Test details error for one pool and success for the other."""
+ mock_ondilo_client.get_ICO_details.side_effect = [
+ OndiloError(
+ 404,
+ "Not Found",
+ ),
+ ico_details2,
+ ]
+
+ await setup_integration(hass, config_entry, mock_ondilo_client)
+
+ device_entries = dr.async_entries_for_config_entry(
+ device_registry, config_entry.entry_id
+ )
+
+ assert len(device_entries) == 1
+
+
+async def test_measures_error_one_pool(
+ hass: HomeAssistant,
+ mock_ondilo_client: MagicMock,
+ device_registry: dr.DeviceRegistry,
+ config_entry: MockConfigEntry,
+ last_measures: list[dict[str, Any]],
+) -> None:
+ """Test measures error for one pool and success for the other."""
+ mock_ondilo_client.get_last_pool_measures.side_effect = [
+ OndiloError(
+ 404,
+ "Not Found",
+ ),
+ last_measures,
+ ]
+
+ await setup_integration(hass, config_entry, mock_ondilo_client)
+
+ device_entries = dr.async_entries_for_config_entry(
+ device_registry, config_entry.entry_id
+ )
+
+ assert len(device_entries) == 1