Skip to content

Commit

Permalink
Detect incorrect exception in forwarded platforms (#117754)
Browse files Browse the repository at this point in the history
* Detect incorrect exception in forwarded platforms

If an integration raises ConfigEntryError/ConfigEntryAuthFailed/ConfigEntryAuthFailed
in a forwarded platform it would affect the state of the config entry and cause it to
process unloads and setup retries in while the other platforms continued to setup

* Detect incorrect exception in forwarded platforms

If an integration raises ConfigEntryError/ConfigEntryAuthFailed/ConfigEntryAuthFailed
in a forwarded platform it would affect the state of the config entry and cause it to
process unloads and setup retries in while the other platforms continued to setup

* Update homeassistant/config_entries.py

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>

* adjust

* fix

---------

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
  • Loading branch information
bdraco and balloob committed May 21, 2024
1 parent 4d447ee commit 7714f80
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 1 deletion.
18 changes: 17 additions & 1 deletion homeassistant/helpers/entity_platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@
split_entity_id,
valid_entity_id,
)
from homeassistant.exceptions import HomeAssistantError, PlatformNotReady
from homeassistant.exceptions import (
ConfigEntryAuthFailed,
ConfigEntryError,
ConfigEntryNotReady,
HomeAssistantError,
PlatformNotReady,
)
from homeassistant.generated import languages
from homeassistant.setup import SetupPhases, async_start_setup
from homeassistant.util.async_ import create_eager_task
Expand Down Expand Up @@ -410,6 +416,16 @@ async def setup_again(*_args: Any) -> None:
SLOW_SETUP_MAX_WAIT,
)
return False
except (ConfigEntryNotReady, ConfigEntryAuthFailed, ConfigEntryError) as exc:
_LOGGER.error(
"%s raises exception %s in forwarded platform "
"%s; Instead raise %s before calling async_forward_entry_setups",
self.platform_name,
type(exc).__name__,
self.domain,
type(exc).__name__,
)
return False
except Exception:
logger.exception(
"Error while setting up %s platform for %s",
Expand Down
73 changes: 73 additions & 0 deletions tests/test_config_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -5398,3 +5398,76 @@ async def mock_async_setup_entry(hass, entry):
await setup_task
await reload_task
assert setup_calls == 2


@pytest.mark.parametrize(
"exc",
[
ConfigEntryError,
ConfigEntryAuthFailed,
ConfigEntryNotReady,
],
)
async def test_raise_wrong_exception_in_forwarded_platform(
hass: HomeAssistant,
manager: config_entries.ConfigEntries,
exc: Exception,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test that we can remove an entry."""

async def mock_setup_entry(
hass: HomeAssistant, entry: config_entries.ConfigEntry
) -> bool:
"""Mock setting up entry."""
await hass.config_entries.async_forward_entry_setups(entry, ["light"])
return True

async def mock_unload_entry(
hass: HomeAssistant, entry: config_entries.ConfigEntry
) -> bool:
"""Mock unloading an entry."""
result = await hass.config_entries.async_unload_platforms(entry, ["light"])
assert result
return result

mock_remove_entry = AsyncMock(return_value=None)

async def mock_setup_entry_platform(
hass: HomeAssistant,
entry: config_entries.ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Mock setting up platform."""
raise exc

mock_integration(
hass,
MockModule(
"test",
async_setup_entry=mock_setup_entry,
async_unload_entry=mock_unload_entry,
async_remove_entry=mock_remove_entry,
),
)
mock_platform(
hass, "test.light", MockPlatform(async_setup_entry=mock_setup_entry_platform)
)
mock_platform(hass, "test.config_flow", None)

entry = MockConfigEntry(domain="test", entry_id="test2")
entry.add_to_manager(manager)

# Setup entry
await manager.async_setup(entry.entry_id)
await hass.async_block_till_done()

exc_type_name = type(exc()).__name__
assert (
f"test raises exception {exc_type_name} in forwarded platform light;"
in caplog.text
)
assert (
f"Instead raise {exc_type_name} before calling async_forward_entry_setups"
in caplog.text
)

0 comments on commit 7714f80

Please sign in to comment.