Improve the error messages returned from jinja template processing. Try to find the actual line with an error in it.

This commit is contained in:
Dan 2021-11-22 14:46:33 -05:00
parent 12b78c1f99
commit 5bb7dbfb19
3 changed files with 26 additions and 9 deletions

View File

@ -3,6 +3,7 @@ import json
from SpiffWorkflow import WorkflowException from SpiffWorkflow import WorkflowException
from SpiffWorkflow.exceptions import WorkflowTaskExecException from SpiffWorkflow.exceptions import WorkflowTaskExecException
from flask import g from flask import g
from jinja2 import TemplateError
from werkzeug.exceptions import InternalServerError from werkzeug.exceptions import InternalServerError
from crc import ma, app from crc import ma, app
@ -111,8 +112,6 @@ class ApiError(Exception):
return ApiError.from_task_spec(code, message, exp.sender) return ApiError.from_task_spec(code, message, exp.sender)
class ApiErrorSchema(ma.Schema): class ApiErrorSchema(ma.Schema):
class Meta: class Meta:
fields = ("code", "message", "workflow_name", "file_name", "task_name", "task_id", fields = ("code", "message", "workflow_name", "file_name", "task_name", "task_id",

View File

@ -1,6 +1,8 @@
import copy import copy
import json import json
import string import string
import sys
import traceback
from datetime import datetime from datetime import datetime
import random import random
import string import string
@ -758,12 +760,24 @@ class WorkflowService(object):
try: try:
return JinjaService.get_content(raw_doc, spiff_task.data) return JinjaService.get_content(raw_doc, spiff_task.data)
except jinja2.exceptions.TemplateError as ue: except jinja2.exceptions.TemplateSyntaxError as tse:
raise ApiError.from_task(code="template_error", message="Error processing template for task %s: %s" % error_line = documentation.splitlines()[tse.lineno - 1]
(spiff_task.task_spec.name, str(ue)), task=spiff_task) raise ApiError.from_task(code="template_error", message="Jinja Template Error: %s" % str(tse),
task=spiff_task, line_number=tse.lineno, error_line=error_line)
except jinja2.exceptions.TemplateError as te:
# Figure out the line number in the template that caused the error.
cl, exc, tb = sys.exc_info()
line_number = None
error_line = None
for frameSummary in traceback.extract_tb(tb):
if frameSummary.filename == '<template>':
line_number = frameSummary.lineno
error_line = documentation.splitlines()[line_number - 1]
raise ApiError.from_task(code="template_error", message="Jinja Template Error: %s" % str(te),
task=spiff_task, line_number=line_number, error_line=error_line)
except TypeError as te: except TypeError as te:
raise ApiError.from_task(code="template_error", message="Error processing template for task %s: %s" % raise ApiError.from_task(code="template_error", message="Jinja Template Error: %s" % str(te),
(spiff_task.task_spec.name, str(te)), task=spiff_task) task=spiff_task)
except Exception as e: except Exception as e:
app.logger.error(str(e), exc_info=True) app.logger.error(str(e), exc_info=True)

View File

@ -13,11 +13,15 @@ class TestValidateEndEvent(BaseTest):
mock_get.return_value.ok = True mock_get.return_value.ok = True
mock_get.return_value.text = self.protocol_builder_response('study_details.json') mock_get.return_value.text = self.protocol_builder_response('study_details.json')
error_string = """ApiError: Error processing template for task EndEvent_1qvyxg7: expected token 'end of statement block', got '='. In file verify_end_event.bpmn. """ error_string = """Jinja Template Error: expected token 'end of statement block', got '='"""
self.load_example_data() self.load_example_data()
spec_model = self.load_test_spec('verify_end_event') spec_model = self.load_test_spec('verify_end_event')
try: try:
WorkflowService.test_spec(spec_model.id) WorkflowService.test_spec(spec_model.id)
except ApiError as e: except ApiError as e:
self.assertEqual(str(e), error_string) self.assertEqual(error_string, e.message)
self.assertEqual('template_error', e.code)
self.assertEqual(8, e.line_number)
self.assertEqual('{%- if value = 1 -%}', e.error_line)
self.assertEqual('verify_end_event.bpmn', e.file_name)