From 1ae33591fccb199adaeef4b3ffde3207b58b90b7 Mon Sep 17 00:00:00 2001 From: Renat Akhmerov Date: Fri, 18 Nov 2016 15:44:57 +0700 Subject: [PATCH] Make YAQL evaluator catch and wrap all underlying exceptions Change-Id: I8bdfd00dfd2ba9e86adc9e5961e5736cd792cf41 Partial-Bug: 1642574 --- mistral/expressions/yaql_expression.py | 2 +- .../tests/unit/engine/test_error_handling.py | 36 +++++++++++++++++++ mistral/workflow/data_flow.py | 9 +++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/mistral/expressions/yaql_expression.py b/mistral/expressions/yaql_expression.py index 61702286..61f2e9c4 100644 --- a/mistral/expressions/yaql_expression.py +++ b/mistral/expressions/yaql_expression.py @@ -55,7 +55,7 @@ class YAQLEvaluator(Evaluator): result = YAQL_ENGINE(expression).evaluate( context=expression_utils.get_yaql_context(data_context) ) - except (yaql_exc.YaqlException, KeyError, ValueError, TypeError) as e: + except Exception as e: raise exc.YaqlEvaluationException( "Can not evaluate YAQL expression [expression=%s, error=%s" ", data=%s]" % (expression, str(e), data_context) diff --git a/mistral/tests/unit/engine/test_error_handling.py b/mistral/tests/unit/engine/test_error_handling.py index b12b1e4d..bf636c32 100644 --- a/mistral/tests/unit/engine/test_error_handling.py +++ b/mistral/tests/unit/engine/test_error_handling.py @@ -586,3 +586,39 @@ class ErrorHandlingEngineTest(base.EngineTestCase): self.assertIsNotNone(state_info) self.assertTrue(state_info.find('error=') > 0) self.assertTrue(state_info.find('error=') < state_info.find('action=')) + + def test_publish_bad_yaql(self): + wf_text = """--- + version: '2.0' + + wf: + type: direct + + input: + - my_dict: + - id: 1 + value: 11 + + tasks: + task1: + action: std.noop + publish: + problem_var: <% $.my_dict.where($.value = 13).id.first() %> + """ + + wf_service.create_workflows(wf_text) + + wf_ex = self.engine.start_workflow('wf', {}) + + self.await_workflow_error(wf_ex.id) + + with db_api.transaction(): + wf_ex = db_api.get_workflow_execution(wf_ex.id) + + task_ex = wf_ex.task_executions[0] + action_ex = task_ex.action_executions[0] + + self.assertEqual(states.SUCCESS, action_ex.state) + self.assertEqual(states.ERROR, task_ex.state) + self.assertIsNotNone(task_ex.state_info) + self.assertEqual(states.ERROR, wf_ex.state) diff --git a/mistral/workflow/data_flow.py b/mistral/workflow/data_flow.py index 7b7fd8c8..a9e32be9 100644 --- a/mistral/workflow/data_flow.py +++ b/mistral/workflow/data_flow.py @@ -200,9 +200,12 @@ def publish_variables(task_ex, task_spec): task_ex.name ) - data = (task_spec.get_publish() - if task_ex.state == states.SUCCESS - else task_spec.get_publish_on_error()) + data = ( + task_spec.get_publish() + if task_ex.state == states.SUCCESS + else task_spec.get_publish_on_error() + ) + task_ex.published = expr.evaluate_recursively(data, expr_ctx)