Add a helpful message to the config_entries.OperationNotAllowed exception (#78631)

We only expect this exception to be raised as a result of an
implementation problem. When it is raised during production
it is currently hard to trace down why its happening

See #75835
This commit is contained in:
J. Nick Koston 2022-09-17 12:52:28 -05:00 committed by GitHub
parent 943fe657c5
commit 74f7ae409b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 7 deletions

View File

@ -1039,7 +1039,10 @@ class ConfigEntries:
raise UnknownEntry
if entry.state is not ConfigEntryState.NOT_LOADED:
raise OperationNotAllowed
raise OperationNotAllowed(
f"The config entry {entry.title} ({entry.domain}) with entry_id {entry.entry_id}"
f" cannot be setup because is already loaded in the {entry.state} state"
)
# Setup Component if not set up yet
if entry.domain in self.hass.config.components:
@ -1061,7 +1064,10 @@ class ConfigEntries:
raise UnknownEntry
if not entry.state.recoverable:
raise OperationNotAllowed
raise OperationNotAllowed(
f"The config entry {entry.title} ({entry.domain}) with entry_id "
f"{entry.entry_id} cannot be unloaded because it is not in a recoverable state ({entry.state})"
)
return await entry.async_unload(self.hass)

View File

@ -1141,7 +1141,7 @@ async def test_entry_setup_invalid_state(hass, manager, state):
MockModule("comp", async_setup=mock_setup, async_setup_entry=mock_setup_entry),
)
with pytest.raises(config_entries.OperationNotAllowed):
with pytest.raises(config_entries.OperationNotAllowed, match=str(state)):
assert await manager.async_setup(entry.entry_id)
assert len(mock_setup.mock_calls) == 0
@ -1201,7 +1201,7 @@ async def test_entry_unload_invalid_state(hass, manager, state):
mock_integration(hass, MockModule("comp", async_unload_entry=async_unload_entry))
with pytest.raises(config_entries.OperationNotAllowed):
with pytest.raises(config_entries.OperationNotAllowed, match=str(state)):
assert await manager.async_unload(entry.entry_id)
assert len(async_unload_entry.mock_calls) == 0
@ -1296,7 +1296,7 @@ async def test_entry_reload_error(hass, manager, state):
),
)
with pytest.raises(config_entries.OperationNotAllowed):
with pytest.raises(config_entries.OperationNotAllowed, match=str(state)):
assert await manager.async_reload(entry.entry_id)
assert len(async_unload_entry.mock_calls) == 0
@ -1370,7 +1370,10 @@ async def test_entry_disable_without_reload_support(hass, manager):
assert entry.state is config_entries.ConfigEntryState.FAILED_UNLOAD
# Enable
with pytest.raises(config_entries.OperationNotAllowed):
with pytest.raises(
config_entries.OperationNotAllowed,
match=str(config_entries.ConfigEntryState.FAILED_UNLOAD),
):
await manager.async_set_disabled_by(entry.entry_id, None)
assert len(async_setup.mock_calls) == 0
assert len(async_setup_entry.mock_calls) == 0
@ -3270,7 +3273,10 @@ async def test_disallow_entry_reload_with_setup_in_progresss(hass, manager):
)
entry.add_to_hass(hass)
with pytest.raises(config_entries.OperationNotAllowed):
with pytest.raises(
config_entries.OperationNotAllowed,
match=str(config_entries.ConfigEntryState.SETUP_IN_PROGRESS),
):
assert await manager.async_reload(entry.entry_id)
assert entry.state is config_entries.ConfigEntryState.SETUP_IN_PROGRESS