diff --git a/homeassistant/bootstrap.py b/homeassistant/bootstrap.py index 9ba4e99a082..eb3aa3a2239 100644 --- a/homeassistant/bootstrap.py +++ b/homeassistant/bootstrap.py @@ -515,16 +515,15 @@ async def async_setup_multi_components( ) for domain in domains } - await asyncio.wait(futures.values()) - errors = [domain for domain in domains if futures[domain].exception()] - for domain in errors: - exception = futures[domain].exception() - assert exception is not None - _LOGGER.error( - "Error setting up integration %s - received exception", - domain, - exc_info=(type(exception), exception, exception.__traceback__), - ) + results = await asyncio.gather(*futures.values(), return_exceptions=True) + for idx, domain in enumerate(futures): + result = results[idx] + if isinstance(result, BaseException): + _LOGGER.error( + "Error setting up integration %s - received exception", + domain, + exc_info=(type(result), result, result.__traceback__), + ) async def _async_set_up_integrations( diff --git a/tests/test_bootstrap.py b/tests/test_bootstrap.py index 9f02d6394e0..cd0d7ef069e 100644 --- a/tests/test_bootstrap.py +++ b/tests/test_bootstrap.py @@ -806,3 +806,26 @@ async def test_warning_logged_on_wrap_up_timeout( await hass.async_block_till_done() assert "Setup timed out for bootstrap - moving forward" in caplog.text + + +@pytest.mark.parametrize("load_registries", [False]) +async def test_bootstrap_is_cancellation_safe( + hass: HomeAssistant, caplog: pytest.LogCaptureFixture +) -> None: + """Test cancellation during async_setup_component does not cancel bootstrap.""" + with patch.object( + bootstrap, "async_setup_component", side_effect=asyncio.CancelledError + ): + await bootstrap._async_set_up_integrations(hass, {"cancel_integration": {}}) + await hass.async_block_till_done() + + assert "Error setting up integration cancel_integration" in caplog.text + + +@pytest.mark.parametrize("load_registries", [False]) +async def test_bootstrap_empty_integrations( + hass: HomeAssistant, caplog: pytest.LogCaptureFixture +) -> None: + """Test setting up an empty integrations does not raise.""" + await bootstrap.async_setup_multi_components(hass, set(), {}) + await hass.async_block_till_done()