mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-05-28 18:43:40 +00:00
refactor(manager): enhance API error handling and fallback logic
Improve error handling for API fetch failures by implementing a fallback to cached intervals. This ensures the system can continue functioning during transient API issues. Impact: Users experience fewer interruptions when the API is temporarily unavailable, as cached data will be used seamlessly.
This commit is contained in:
parent
bf95dc5efc
commit
27ab58bbf5
1 changed files with 31 additions and 10 deletions
|
|
@ -9,7 +9,10 @@ from datetime import UTC, datetime, timedelta
|
||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
from zoneinfo import ZoneInfo
|
from zoneinfo import ZoneInfo
|
||||||
|
|
||||||
from custom_components.tibber_prices.api.exceptions import TibberPricesApiClientError
|
from custom_components.tibber_prices.api.exceptions import (
|
||||||
|
TibberPricesApiClientCommunicationError,
|
||||||
|
TibberPricesApiClientError,
|
||||||
|
)
|
||||||
from homeassistant.util import dt as dt_utils
|
from homeassistant.util import dt as dt_utils
|
||||||
|
|
||||||
from .cache import TibberPricesIntervalPoolFetchGroupCache
|
from .cache import TibberPricesIntervalPoolFetchGroupCache
|
||||||
|
|
@ -201,9 +204,11 @@ class TibberPricesIntervalPool:
|
||||||
)
|
)
|
||||||
|
|
||||||
# Fetch missing ranges from API
|
# Fetch missing ranges from API
|
||||||
|
api_fetch_failed = False
|
||||||
if missing_ranges:
|
if missing_ranges:
|
||||||
fetch_time_iso = dt_utils.now().isoformat()
|
fetch_time_iso = dt_utils.now().isoformat()
|
||||||
|
|
||||||
|
try:
|
||||||
# Fetch with callback for immediate caching
|
# Fetch with callback for immediate caching
|
||||||
await self._fetcher.fetch_missing_ranges(
|
await self._fetcher.fetch_missing_ranges(
|
||||||
api_client=api_client,
|
api_client=api_client,
|
||||||
|
|
@ -211,13 +216,29 @@ class TibberPricesIntervalPool:
|
||||||
missing_ranges=missing_ranges,
|
missing_ranges=missing_ranges,
|
||||||
on_intervals_fetched=lambda intervals, _: self._add_intervals(intervals, fetch_time_iso),
|
on_intervals_fetched=lambda intervals, _: self._add_intervals(intervals, fetch_time_iso),
|
||||||
)
|
)
|
||||||
|
except TibberPricesApiClientCommunicationError as err:
|
||||||
|
if cached_intervals:
|
||||||
|
# Transient API error (e.g. 503) but we have cached data - use it as
|
||||||
|
# fallback so the coordinator can finish initializing. The next regular
|
||||||
|
# update cycle will retry the API automatically.
|
||||||
|
_LOGGER.warning(
|
||||||
|
"API temporarily unavailable for home %s (%s) - using %d cached intervals as fallback",
|
||||||
|
self._home_id,
|
||||||
|
err,
|
||||||
|
len(cached_intervals),
|
||||||
|
)
|
||||||
|
api_fetch_failed = True
|
||||||
|
else:
|
||||||
|
# No cached data at all - re-raise so the caller can decide
|
||||||
|
raise
|
||||||
|
|
||||||
# After caching all API responses, read from cache again to get final result
|
# After caching all API responses, read from cache again to get final result
|
||||||
# This ensures we return exactly what user requested, filtering out extra intervals
|
# This ensures we return exactly what user requested, filtering out extra intervals
|
||||||
final_result = self._get_cached_intervals(start_time_iso, end_time_iso)
|
final_result = self._get_cached_intervals(start_time_iso, end_time_iso)
|
||||||
|
|
||||||
# Track if API was called (True if any missing ranges were fetched)
|
# Track if API was called (True if any missing ranges were attempted)
|
||||||
api_called = len(missing_ranges) > 0
|
# If fetch failed but we fell back to cache, treat as "no API call succeeded"
|
||||||
|
api_called = len(missing_ranges) > 0 and not api_fetch_failed
|
||||||
|
|
||||||
_LOGGER_DETAILS.debug(
|
_LOGGER_DETAILS.debug(
|
||||||
"Pool returning %d intervals for home %s (from cache: %d, fetched from API: %d ranges, api_called=%s)",
|
"Pool returning %d intervals for home %s (from cache: %d, fetched from API: %d ranges, api_called=%s)",
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue