Retry ZHA config entry setup when `ENETUNREACH` is caught (#84615)
* The config entry is not ready on `ENETUNREACH` * Use new `TransientConnectionError` from zigpypull/85481/head
parent
7e6b087773
commit
7396bcc585
|
@ -17,6 +17,7 @@ from zigpy.application import ControllerApplication
|
||||||
from zigpy.config import CONF_DEVICE
|
from zigpy.config import CONF_DEVICE
|
||||||
import zigpy.device
|
import zigpy.device
|
||||||
import zigpy.endpoint
|
import zigpy.endpoint
|
||||||
|
import zigpy.exceptions
|
||||||
import zigpy.group
|
import zigpy.group
|
||||||
from zigpy.types.named import EUI64
|
from zigpy.types.named import EUI64
|
||||||
|
|
||||||
|
@ -24,6 +25,7 @@ from homeassistant import __path__ as HOMEASSISTANT_PATH
|
||||||
from homeassistant.components.system_log import LogEntry, _figure_out_source
|
from homeassistant.components.system_log import LogEntry, _figure_out_source
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||||
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
from homeassistant.helpers.dispatcher import async_dispatcher_send
|
||||||
from homeassistant.helpers.entity import DeviceInfo
|
from homeassistant.helpers.entity import DeviceInfo
|
||||||
|
@ -172,6 +174,8 @@ class ZHAGateway:
|
||||||
self.application_controller = await app_controller_cls.new(
|
self.application_controller = await app_controller_cls.new(
|
||||||
app_config, auto_form=True, start_radio=True
|
app_config, auto_form=True, start_radio=True
|
||||||
)
|
)
|
||||||
|
except zigpy.exceptions.TransientConnectionError as exc:
|
||||||
|
raise ConfigEntryNotReady from exc
|
||||||
except Exception as exc: # pylint: disable=broad-except
|
except Exception as exc: # pylint: disable=broad-except
|
||||||
_LOGGER.warning(
|
_LOGGER.warning(
|
||||||
"Couldn't start %s coordinator (attempt %s of %s)",
|
"Couldn't start %s coordinator (attempt %s of %s)",
|
||||||
|
|
|
@ -3,12 +3,14 @@ import asyncio
|
||||||
from unittest.mock import AsyncMock, MagicMock, patch
|
from unittest.mock import AsyncMock, MagicMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import zigpy.exceptions
|
||||||
import zigpy.profiles.zha as zha
|
import zigpy.profiles.zha as zha
|
||||||
import zigpy.zcl.clusters.general as general
|
import zigpy.zcl.clusters.general as general
|
||||||
import zigpy.zcl.clusters.lighting as lighting
|
import zigpy.zcl.clusters.lighting as lighting
|
||||||
|
|
||||||
from homeassistant.components.zha.core.group import GroupMember
|
from homeassistant.components.zha.core.group import GroupMember
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
|
|
||||||
from .common import async_find_group_entity_id, get_zha_gateway
|
from .common import async_find_group_entity_id, get_zha_gateway
|
||||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||||
|
@ -259,3 +261,20 @@ async def test_gateway_initialize_failure(hass, device_light_1, coordinator):
|
||||||
await zha_gateway.async_initialize()
|
await zha_gateway.async_initialize()
|
||||||
|
|
||||||
assert mock_new.call_count == 3
|
assert mock_new.call_count == 3
|
||||||
|
|
||||||
|
|
||||||
|
@patch("homeassistant.components.zha.core.gateway.STARTUP_FAILURE_DELAY_S", 0.01)
|
||||||
|
async def test_gateway_initialize_failure_transient(hass, device_light_1, coordinator):
|
||||||
|
"""Test ZHA failing to initialize the gateway but with a transient error."""
|
||||||
|
zha_gateway = get_zha_gateway(hass)
|
||||||
|
assert zha_gateway is not None
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"bellows.zigbee.application.ControllerApplication.new",
|
||||||
|
side_effect=[RuntimeError(), zigpy.exceptions.TransientConnectionError()],
|
||||||
|
) as mock_new:
|
||||||
|
with pytest.raises(ConfigEntryNotReady):
|
||||||
|
await zha_gateway.async_initialize()
|
||||||
|
|
||||||
|
# Initialization immediately stops and is retried after TransientConnectionError
|
||||||
|
assert mock_new.call_count == 2
|
||||||
|
|
Loading…
Reference in New Issue