From c48b724dde1887849f4464c6a27ffbfc1c55021c Mon Sep 17 00:00:00 2001 From: Mike Woudenberg Date: Sun, 8 Oct 2023 19:00:06 +0200 Subject: [PATCH] Make setup more resilient by raising ConfigNEntryNotReady on failure (#101654) Make setup more resilient by raising ConfigNEntryNotReady on connection failure --- homeassistant/components/loqed/__init__.py | 23 ++++++++++++++++------ tests/components/loqed/test_init.py | 17 ++++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/homeassistant/components/loqed/__init__.py b/homeassistant/components/loqed/__init__.py index 3ee65f751ae..cc43baab1c8 100644 --- a/homeassistant/components/loqed/__init__.py +++ b/homeassistant/components/loqed/__init__.py @@ -1,14 +1,17 @@ """The loqed integration.""" from __future__ import annotations +import asyncio import logging import re +import aiohttp from loqedAPI import loqed from homeassistant.config_entries import ConfigEntry from homeassistant.const import Platform from homeassistant.core import HomeAssistant +from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import DOMAIN @@ -27,12 +30,20 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: apiclient = loqed.APIClient(websession, f"http://{host}") api = loqed.LoqedAPI(apiclient) - lock = await api.async_get_lock( - entry.data["lock_key_key"], - entry.data["bridge_key"], - int(entry.data["lock_key_local_id"]), - re.sub(r"LOQED-([a-f0-9]+)\.local", r"\1", entry.data["bridge_mdns_hostname"]), - ) + try: + lock = await api.async_get_lock( + entry.data["lock_key_key"], + entry.data["bridge_key"], + int(entry.data["lock_key_local_id"]), + re.sub( + r"LOQED-([a-f0-9]+)\.local", r"\1", entry.data["bridge_mdns_hostname"] + ), + ) + except ( + asyncio.TimeoutError, + aiohttp.ClientError, + ) as ex: + raise ConfigEntryNotReady(f"Unable to connect to bridge at {host}") from ex coordinator = LoqedDataCoordinator(hass, api, lock, entry) await coordinator.ensure_webhooks() diff --git a/tests/components/loqed/test_init.py b/tests/components/loqed/test_init.py index 057061f5915..47f53a1ad20 100644 --- a/tests/components/loqed/test_init.py +++ b/tests/components/loqed/test_init.py @@ -4,6 +4,7 @@ import json from typing import Any from unittest.mock import AsyncMock, patch +import aiohttp from loqedAPI import loqed from homeassistant.components.loqed.const import DOMAIN @@ -58,6 +59,22 @@ async def test_setup_webhook_in_bridge( lock.registerWebhook.assert_called_with(f"{get_url(hass)}/api/webhook/Webhook_id") +async def test_cannot_connect_to_bridge_will_retry( + hass: HomeAssistant, config_entry: MockConfigEntry, lock: loqed.Lock +): + """Test webhook setup in loqed bridge.""" + config: dict[str, Any] = {DOMAIN: {}} + config_entry.add_to_hass(hass) + + with patch( + "loqedAPI.loqed.LoqedAPI.async_get_lock", side_effect=aiohttp.ClientError + ): + await async_setup_component(hass, DOMAIN, config) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.SETUP_RETRY + + async def test_setup_cloudhook_in_bridge( hass: HomeAssistant, config_entry: MockConfigEntry, lock: loqed.Lock ):