diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 3d43e03ddce..0b755ae0032 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -205,6 +205,10 @@ async def trace_action(hass, script_run, stop, variables): except _AbortScript as ex: trace_element.set_error(ex.__cause__ or 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: raise ex except Exception as ex: @@ -325,11 +329,19 @@ async def async_validate_action_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.""" -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.""" @@ -393,16 +405,18 @@ class _ScriptRun: await self._async_step(log_exceptions=False) else: 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: script_execution_set("aborted") # Let the _AbortScript bubble up if this is a sub-script if not self._script.top_level: 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: script_execution_set("error") raise @@ -450,7 +464,7 @@ class _ScriptRun: def _handle_exception( self, exception: Exception, continue_on_error: bool, log_exceptions: bool ) -> None: - if not isinstance(exception, (_AbortScript, _StopScript)) and log_exceptions: + if not isinstance(exception, _HaltScript) and log_exceptions: self._log_exception(exception) if not continue_on_error: @@ -726,7 +740,7 @@ class _ScriptRun: self._log("Test condition %s: %s", self._script.last_action, check) trace_update_result(result=check) if not check: - raise _AbortScript + raise _ConditionFail def _test_conditions(self, conditions, name, condition_path=None): if condition_path is None: diff --git a/tests/helpers/test_script.py b/tests/helpers/test_script.py index 4791dd84cc4..c01f086a12a 100644 --- a/tests/helpers/test_script.py +++ b/tests/helpers/test_script.py @@ -1445,7 +1445,7 @@ async def test_condition_warning(hass, caplog): assert_action_trace( { "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}], }, expected_script_execution="aborted", @@ -1499,7 +1499,6 @@ async def test_condition_basic(hass, caplog): "0": [{"result": {"event": "test_event", "event_data": {}}}], "1": [ { - "error_type": script._AbortScript, "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": {}}}], "1": [ { - "error_type": script._AbortScript, "result": {"entities": ["test.entity"], "result": False}, } ], @@ -1656,7 +1654,6 @@ async def test_condition_validation(hass, caplog): "0": [{"result": {"event": "test_event", "event_data": {}}}], "1": [ { - "error_type": script._AbortScript, "result": {"result": False}, } ],