Fix script conditions (#71235)

This commit is contained in:
Erik Montnemery 2022-05-03 11:28:08 +02:00 committed by GitHub
parent 1931600eac
commit 92f1855bcf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 13 deletions

View file

@ -205,6 +205,10 @@ async def trace_action(hass, script_run, stop, variables):
except _AbortScript as ex: except _AbortScript as ex:
trace_element.set_error(ex.__cause__ or ex) trace_element.set_error(ex.__cause__ or ex)
raise ex raise ex
except _ConditionFail as ex:
# Clear errors which may have been set when evaluating the condition
trace_element.set_error(None)
raise ex
except _StopScript as ex: except _StopScript as ex:
raise ex raise ex
except Exception as ex: except Exception as ex:
@ -325,11 +329,19 @@ async def async_validate_action_config(
return config return config
class _AbortScript(Exception): class _HaltScript(Exception):
"""Throw if script needs to stop executing."""
class _AbortScript(_HaltScript):
"""Throw if script needs to abort because of an unexpected error.""" """Throw if script needs to abort because of an unexpected error."""
class _StopScript(Exception): class _ConditionFail(_HaltScript):
"""Throw if script needs to stop because a condition evaluated to False."""
class _StopScript(_HaltScript):
"""Throw if script needs to stop.""" """Throw if script needs to stop."""
@ -393,16 +405,18 @@ class _ScriptRun:
await self._async_step(log_exceptions=False) await self._async_step(log_exceptions=False)
else: else:
script_execution_set("finished") script_execution_set("finished")
except _StopScript:
script_execution_set("finished")
# Let the _StopScript bubble up if this is a sub-script
if not self._script.top_level:
raise
except _AbortScript: except _AbortScript:
script_execution_set("aborted") script_execution_set("aborted")
# Let the _AbortScript bubble up if this is a sub-script # Let the _AbortScript bubble up if this is a sub-script
if not self._script.top_level: if not self._script.top_level:
raise raise
except _ConditionFail:
script_execution_set("aborted")
except _StopScript:
script_execution_set("finished")
# Let the _StopScript bubble up if this is a sub-script
if not self._script.top_level:
raise
except Exception: except Exception:
script_execution_set("error") script_execution_set("error")
raise raise
@ -450,7 +464,7 @@ class _ScriptRun:
def _handle_exception( def _handle_exception(
self, exception: Exception, continue_on_error: bool, log_exceptions: bool self, exception: Exception, continue_on_error: bool, log_exceptions: bool
) -> None: ) -> None:
if not isinstance(exception, (_AbortScript, _StopScript)) and log_exceptions: if not isinstance(exception, _HaltScript) and log_exceptions:
self._log_exception(exception) self._log_exception(exception)
if not continue_on_error: if not continue_on_error:
@ -726,7 +740,7 @@ class _ScriptRun:
self._log("Test condition %s: %s", self._script.last_action, check) self._log("Test condition %s: %s", self._script.last_action, check)
trace_update_result(result=check) trace_update_result(result=check)
if not check: if not check:
raise _AbortScript raise _ConditionFail
def _test_conditions(self, conditions, name, condition_path=None): def _test_conditions(self, conditions, name, condition_path=None):
if condition_path is None: if condition_path is None:

View file

@ -1445,7 +1445,7 @@ async def test_condition_warning(hass, caplog):
assert_action_trace( assert_action_trace(
{ {
"0": [{"result": {"event": "test_event", "event_data": {}}}], "0": [{"result": {"event": "test_event", "event_data": {}}}],
"1": [{"error_type": script._AbortScript, "result": {"result": False}}], "1": [{"result": {"result": False}}],
"1/entity_id/0": [{"error_type": ConditionError}], "1/entity_id/0": [{"error_type": ConditionError}],
}, },
expected_script_execution="aborted", expected_script_execution="aborted",
@ -1499,7 +1499,6 @@ async def test_condition_basic(hass, caplog):
"0": [{"result": {"event": "test_event", "event_data": {}}}], "0": [{"result": {"event": "test_event", "event_data": {}}}],
"1": [ "1": [
{ {
"error_type": script._AbortScript,
"result": {"entities": ["test.entity"], "result": False}, "result": {"entities": ["test.entity"], "result": False},
} }
], ],
@ -1590,7 +1589,6 @@ async def test_shorthand_template_condition(hass, caplog):
"0": [{"result": {"event": "test_event", "event_data": {}}}], "0": [{"result": {"event": "test_event", "event_data": {}}}],
"1": [ "1": [
{ {
"error_type": script._AbortScript,
"result": {"entities": ["test.entity"], "result": False}, "result": {"entities": ["test.entity"], "result": False},
} }
], ],
@ -1656,7 +1654,6 @@ async def test_condition_validation(hass, caplog):
"0": [{"result": {"event": "test_event", "event_data": {}}}], "0": [{"result": {"event": "test_event", "event_data": {}}}],
"1": [ "1": [
{ {
"error_type": script._AbortScript,
"result": {"result": False}, "result": {"result": False},
} }
], ],