Create async_config_entry_first_refresh to reduce coordinator boilerplate (#48451)
This commit is contained in:
parent
569c536a8e
commit
a851bff95a
57 changed files with 181 additions and 225 deletions
|
@ -13,6 +13,7 @@ import requests
|
|||
|
||||
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import CALLBACK_TYPE, Event, HassJob, HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers import entity, event
|
||||
from homeassistant.util.dt import utcnow
|
||||
|
||||
|
@ -57,6 +58,7 @@ class DataUpdateCoordinator(Generic[T]):
|
|||
self._unsub_refresh: CALLBACK_TYPE | None = None
|
||||
self._request_refresh_task: asyncio.TimerHandle | None = None
|
||||
self.last_update_success = True
|
||||
self.last_exception: Exception | None = None
|
||||
|
||||
if request_refresh_debouncer is None:
|
||||
request_refresh_debouncer = Debouncer(
|
||||
|
@ -140,7 +142,25 @@ class DataUpdateCoordinator(Generic[T]):
|
|||
raise NotImplementedError("Update method not implemented")
|
||||
return await self.update_method()
|
||||
|
||||
async def async_config_entry_first_refresh(self) -> None:
|
||||
"""Refresh data for the first time when a config entry is setup.
|
||||
|
||||
Will automatically raise ConfigEntryNotReady if the refresh
|
||||
fails. Additionally logging is handled by config entry setup
|
||||
to ensure that multiple retries do not cause log spam.
|
||||
"""
|
||||
await self._async_refresh(log_failures=False)
|
||||
if self.last_update_success:
|
||||
return
|
||||
ex = ConfigEntryNotReady()
|
||||
ex.__cause__ = self.last_exception
|
||||
raise ex
|
||||
|
||||
async def async_refresh(self) -> None:
|
||||
"""Refresh data and log errors."""
|
||||
await self._async_refresh(log_failures=True)
|
||||
|
||||
async def _async_refresh(self, log_failures: bool = True) -> None:
|
||||
"""Refresh data."""
|
||||
if self._unsub_refresh:
|
||||
self._unsub_refresh()
|
||||
|
@ -152,37 +172,50 @@ class DataUpdateCoordinator(Generic[T]):
|
|||
try:
|
||||
self.data = await self._async_update_data()
|
||||
|
||||
except (asyncio.TimeoutError, requests.exceptions.Timeout):
|
||||
except (asyncio.TimeoutError, requests.exceptions.Timeout) as err:
|
||||
self.last_exception = err
|
||||
if self.last_update_success:
|
||||
self.logger.error("Timeout fetching %s data", self.name)
|
||||
if log_failures:
|
||||
self.logger.error("Timeout fetching %s data", self.name)
|
||||
self.last_update_success = False
|
||||
|
||||
except (aiohttp.ClientError, requests.exceptions.RequestException) as err:
|
||||
self.last_exception = err
|
||||
if self.last_update_success:
|
||||
self.logger.error("Error requesting %s data: %s", self.name, err)
|
||||
self.last_update_success = False
|
||||
|
||||
except urllib.error.URLError as err:
|
||||
if self.last_update_success:
|
||||
if err.reason == "timed out":
|
||||
self.logger.error("Timeout fetching %s data", self.name)
|
||||
else:
|
||||
if log_failures:
|
||||
self.logger.error("Error requesting %s data: %s", self.name, err)
|
||||
self.last_update_success = False
|
||||
|
||||
except UpdateFailed as err:
|
||||
except urllib.error.URLError as err:
|
||||
self.last_exception = err
|
||||
if self.last_update_success:
|
||||
self.logger.error("Error fetching %s data: %s", self.name, err)
|
||||
if log_failures:
|
||||
if err.reason == "timed out":
|
||||
self.logger.error("Timeout fetching %s data", self.name)
|
||||
else:
|
||||
self.logger.error(
|
||||
"Error requesting %s data: %s", self.name, err
|
||||
)
|
||||
self.last_update_success = False
|
||||
|
||||
except UpdateFailed as err:
|
||||
self.last_exception = err
|
||||
if self.last_update_success:
|
||||
if log_failures:
|
||||
self.logger.error("Error fetching %s data: %s", self.name, err)
|
||||
self.last_update_success = False
|
||||
|
||||
except NotImplementedError as err:
|
||||
self.last_exception = err
|
||||
raise err
|
||||
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
self.last_exception = err
|
||||
self.last_update_success = False
|
||||
self.logger.exception(
|
||||
"Unexpected error fetching %s data: %s", self.name, err
|
||||
)
|
||||
if log_failures:
|
||||
self.logger.exception(
|
||||
"Unexpected error fetching %s data: %s", self.name, err
|
||||
)
|
||||
|
||||
else:
|
||||
if not self.last_update_success:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue