diff --git a/homeassistant/components/tplink/config_flow.py b/homeassistant/components/tplink/config_flow.py index a0f0ca6eb76..1c02466aef1 100644 --- a/homeassistant/components/tplink/config_flow.py +++ b/homeassistant/components/tplink/config_flow.py @@ -410,9 +410,18 @@ class TPLinkConfigFlow(ConfigFlow, domain=DOMAIN): self._discovered_device = await Discover.discover_single( host, credentials=credentials ) - except TimeoutError: - # Try connect() to legacy devices if discovery fails - self._discovered_device = await Device.connect(config=DeviceConfig(host)) + except TimeoutError as ex: + # Try connect() to legacy devices if discovery fails. This is a + # fallback mechanism for legacy that can handle connections without + # discovery info but if it fails raise the original error which is + # applicable for newer devices. + try: + self._discovered_device = await Device.connect( + config=DeviceConfig(host) + ) + except Exception: # noqa: BLE001 + # Raise the original error instead of the fallback error + raise ex from ex else: if self._discovered_device.config.uses_http: self._discovered_device.config.http_client = ( diff --git a/tests/components/tplink/test_config_flow.py b/tests/components/tplink/test_config_flow.py index ddd67f249e6..f90eb985d38 100644 --- a/tests/components/tplink/test_config_flow.py +++ b/tests/components/tplink/test_config_flow.py @@ -1289,6 +1289,33 @@ async def test_discovery_timeout_connect( assert mock_connect["connect"].call_count == 1 +async def test_discovery_timeout_connect_legacy_error( + hass: HomeAssistant, + mock_discovery: AsyncMock, + mock_connect: AsyncMock, + mock_init, +) -> None: + """Test discovery tries legacy connect on timeout.""" + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER} + ) + mock_discovery["discover_single"].side_effect = TimeoutError + mock_connect["connect"].side_effect = KasaException + await hass.async_block_till_done() + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" + assert not result["errors"] + assert mock_connect["connect"].call_count == 0 + + result2 = await hass.config_entries.flow.async_configure( + result["flow_id"], {CONF_HOST: IP_ADDRESS} + ) + await hass.async_block_till_done() + assert result2["type"] is FlowResultType.FORM + assert result2["errors"] == {"base": "cannot_connect"} + assert mock_connect["connect"].call_count == 1 + + async def test_reauth_update_other_flows( hass: HomeAssistant, mock_discovery: AsyncMock,