1
mirror of https://github.com/home-assistant/core synced 2024-08-02 23:40:32 +02:00

Raise repairs issue if automation calls unknown service (#76949)

This commit is contained in:
Franck Nijhof 2022-08-26 02:56:26 +02:00 committed by GitHub
parent d7724235ff
commit 5f0cca9b26
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 2 deletions

View File

@ -9,6 +9,7 @@ import voluptuous as vol
from voluptuous.humanize import humanize_error
from homeassistant.components import blueprint
from homeassistant.components.repairs import IssueSeverity, async_create_issue
from homeassistant.const import (
ATTR_ENTITY_ID,
ATTR_MODE,
@ -43,6 +44,7 @@ from homeassistant.exceptions import (
ConditionErrorContainer,
ConditionErrorIndex,
HomeAssistantError,
ServiceNotFound,
TemplateError,
)
from homeassistant.helpers import condition, extract_domain_configs
@ -525,6 +527,23 @@ class AutomationEntity(ToggleEntity, RestoreEntity):
await self.action_script.async_run(
variables, trigger_context, started_action
)
except ServiceNotFound as err:
async_create_issue(
self.hass,
DOMAIN,
f"{self.entity_id}_service_not_found_{err.domain}.{err.service}",
is_fixable=True,
is_persistent=True,
severity=IssueSeverity.ERROR,
translation_key="service_not_found",
translation_placeholders={
"service": f"{err.domain}.{err.service}",
"entity_id": self.entity_id,
"name": self.name or self.entity_id,
"edit": f"/config/automation/edit/{self.unique_id}",
},
)
automation_trace.set_error(err)
except (vol.Invalid, HomeAssistantError) as err:
self._logger.error(
"Error while executing automation %s: %s",

View File

@ -2,7 +2,7 @@
"domain": "automation",
"name": "Automation",
"documentation": "https://www.home-assistant.io/integrations/automation",
"dependencies": ["blueprint", "trace"],
"dependencies": ["blueprint", "repairs", "trace"],
"after_dependencies": ["device_automation", "webhook"],
"codeowners": ["@home-assistant/core"],
"quality_scale": "internal"

View File

@ -5,5 +5,18 @@
"off": "[%key:common::state::off%]",
"on": "[%key:common::state::on%]"
}
},
"issues": {
"service_not_found": {
"title": "{name} uses an unknown service",
"fix_flow": {
"step": {
"confirm": {
"title": "{name} uses an unknown service",
"description": "The automation \"{name}\" (`{entity_id}`) has an action that calls an unknown service: `{service}`.\n\nThis error prevents the automation from running correctly. Maybe this service is no longer available, or perhaps a typo caused it.\n\nTo fix this error, [edit the automation]({edit}) and remove the action that calls this service.\n\nClick on SUBMIT below to confirm you have fixed this automation."
}
}
}
}
}
}

View File

@ -1,4 +1,17 @@
{
"issues": {
"service_not_found": {
"fix_flow": {
"step": {
"confirm": {
"description": "The automation \"{name}\" (`{entity_id}`) has an action that calls an unknown service: `{service}`.\n\nThis error prevents the automation from running correctly. Maybe this service is no longer available, or perhaps a typo caused it.\n\nTo fix this error, [edit the automation]({edit}) and remove the action that calls this service.\n\nClick on SUBMIT below to confirm you have fixed this automation.",
"title": "{name} uses an unknown service"
}
}
},
"title": "{name} uses an unknown service"
}
},
"state": {
"_": {
"off": "Off",

View File

@ -1,9 +1,11 @@
"""The tests for the automation component."""
import asyncio
from collections.abc import Awaitable, Callable
from datetime import timedelta
import logging
from unittest.mock import Mock, patch
from aiohttp import ClientWebSocketResponse
import pytest
import homeassistant.components.automation as automation
@ -53,6 +55,7 @@ from tests.common import (
mock_restore_cache,
)
from tests.components.logbook.common import MockRow, mock_humanify
from tests.components.repairs import get_repairs
@pytest.fixture
@ -983,7 +986,11 @@ async def test_automation_bad_trigger(hass, caplog):
assert "Integration 'automation' does not provide trigger support." in caplog.text
async def test_automation_with_error_in_script(hass, caplog):
async def test_automation_with_error_in_script(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
hass_ws_client: Callable[[HomeAssistant], Awaitable[ClientWebSocketResponse]],
) -> None:
"""Test automation with an error in script."""
assert await async_setup_component(
hass,
@ -1002,6 +1009,10 @@ async def test_automation_with_error_in_script(hass, caplog):
assert "Service not found" in caplog.text
assert "Traceback" not in caplog.text
issues = await get_repairs(hass, hass_ws_client)
assert len(issues) == 1
assert issues[0]["issue_id"] == "automation.hello_service_not_found_test.automation"
async def test_automation_with_error_in_script_2(hass, caplog):
"""Test automation with an error in script."""

View File

@ -75,5 +75,6 @@ async def authed_api_client(hass, hass_client):
@pytest.fixture(autouse=True)
async def setup_ws(hass):
"""Configure the websocket_api component."""
assert await async_setup_component(hass, "repairs", {})
assert await async_setup_component(hass, "websocket_api", {})
await hass.async_block_till_done()

View File

@ -696,6 +696,7 @@ async def test_not_fires_on_mqtt_message_after_remove_from_registry(
):
"""Test triggers not firing after removal."""
assert await async_setup_component(hass, "config", {})
assert await async_setup_component(hass, "repairs", {})
await hass.async_block_till_done()
await mqtt_mock_entry_no_yaml_config()