mirror of
https://github.com/home-assistant/core.git
synced 2026-07-13 17:44:45 +01:00
Don't log configuration errors when executing WS subscribe_trigger (#172918)
This commit is contained in:
@@ -980,7 +980,24 @@ async def handle_subscribe_trigger(
|
||||
hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Handle subscribe trigger command."""
|
||||
trigger_config = await async_validate_trigger_config(hass, msg["trigger"])
|
||||
# Validating the trigger config can fail on bad user input. Handle those
|
||||
# errors here so they are reported to the client without being logged as
|
||||
# unexpected errors by the default websocket error handler.
|
||||
try:
|
||||
trigger_config = await async_validate_trigger_config(hass, msg["trigger"])
|
||||
except vol.Invalid as err:
|
||||
connection.send_error(msg["id"], const.ERR_INVALID_FORMAT, str(err))
|
||||
return
|
||||
except HomeAssistantError as err:
|
||||
connection.send_error(
|
||||
msg["id"],
|
||||
const.ERR_HOME_ASSISTANT_ERROR,
|
||||
str(err),
|
||||
translation_domain=err.translation_domain,
|
||||
translation_key=err.translation_key,
|
||||
translation_placeholders=err.translation_placeholders,
|
||||
)
|
||||
return
|
||||
|
||||
@callback
|
||||
def forward_triggers(
|
||||
|
||||
@@ -2745,6 +2745,103 @@ async def test_subscribe_trigger(
|
||||
assert sum(hass.bus.async_listeners().values()) == init_count
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("trigger", "expected_error"),
|
||||
[
|
||||
# Unknown trigger platform
|
||||
(
|
||||
{"platform": "nonexistent"},
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"message": "Invalid trigger 'nonexistent' specified",
|
||||
},
|
||||
),
|
||||
# Missing mandatory config for the trigger platform
|
||||
(
|
||||
{"platform": "numeric_state"},
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"message": "required key not provided @ data['entity_id']",
|
||||
},
|
||||
),
|
||||
# Unknown device, raised as a HomeAssistantError by the platform validator
|
||||
(
|
||||
{"platform": "device", "domain": "light", "device_id": "nonexistent"},
|
||||
{
|
||||
"code": "home_assistant_error",
|
||||
"message": "Unknown device 'nonexistent'",
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_subscribe_trigger_config_error(
|
||||
hass: HomeAssistant,
|
||||
websocket_client: MockHAClientWebSocket,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
trigger: dict,
|
||||
expected_error: dict,
|
||||
) -> None:
|
||||
"""Test trigger config errors are reported to the client without logging."""
|
||||
caplog.set_level(logging.ERROR)
|
||||
|
||||
await websocket_client.send_json_auto_id(
|
||||
{"type": "subscribe_trigger", "trigger": trigger}
|
||||
)
|
||||
|
||||
msg = await websocket_client.receive_json()
|
||||
assert msg["type"] == const.TYPE_RESULT
|
||||
assert not msg["success"]
|
||||
assert msg["error"] == expected_error
|
||||
|
||||
# The expected error is not logged by the default websocket error handler
|
||||
assert "Error handling message" not in caplog.text
|
||||
|
||||
|
||||
async def test_subscribe_trigger_template_error_spams_log(
|
||||
hass: HomeAssistant,
|
||||
websocket_client: MockHAClientWebSocket,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test that a failing trigger template spams the log.
|
||||
|
||||
This documents unwanted behavior. Unlike subscribe_condition and
|
||||
test_condition, subscribe_trigger does not suppress repeated template
|
||||
variable errors: a trigger is evaluated event-driven by its platform (here
|
||||
via async_track_template_result), outside any trace context, so the
|
||||
trace-based suppression used for conditions does not apply. This should be
|
||||
fixed in the future so the error is suppressed/forwarded instead of being
|
||||
logged on every re-render.
|
||||
"""
|
||||
caplog.set_level(logging.WARNING)
|
||||
hass.states.async_set("sensor.test", "1")
|
||||
|
||||
await websocket_client.send_json_auto_id(
|
||||
{
|
||||
"type": "subscribe_trigger",
|
||||
"trigger": {
|
||||
"platform": "template",
|
||||
"value_template": "{{ states('sensor.test') }}{{ undefined_variable }}",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
msg = await websocket_client.receive_json()
|
||||
assert msg["type"] == const.TYPE_RESULT
|
||||
assert msg["success"]
|
||||
|
||||
# Each re-render of the template logs the undefined variable error again
|
||||
for state in ("2", "3", "4"):
|
||||
hass.states.async_set("sensor.test", state)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert (
|
||||
caplog.text.count(
|
||||
"Template variable warning: 'undefined_variable' is undefined"
|
||||
)
|
||||
> 1
|
||||
)
|
||||
|
||||
|
||||
async def test_test_condition(
|
||||
hass: HomeAssistant, websocket_client: MockHAClientWebSocket
|
||||
) -> None:
|
||||
|
||||
Reference in New Issue
Block a user