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

View File

@ -1,6 +1,8 @@
import copy
import json
import string
import sys
import traceback
from datetime import datetime
import random
import string
@ -758,12 +760,24 @@ class WorkflowService(object):
try:
return JinjaService.get_content(raw_doc, spiff_task.data)
except jinja2.exceptions.TemplateError as ue:
raise ApiError.from_task(code="template_error", message="Error processing template for task %s: %s" %
(spiff_task.task_spec.name, str(ue)), task=spiff_task)
except jinja2.exceptions.TemplateSyntaxError as tse:
error_line = documentation.splitlines()[tse.lineno - 1]
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:
raise ApiError.from_task(code="template_error", message="Error processing template for task %s: %s" %
(spiff_task.task_spec.name, str(te)), task=spiff_task)
raise ApiError.from_task(code="template_error", message="Jinja Template Error: %s" % str(te),
task=spiff_task)
except Exception as e:
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.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()
spec_model = self.load_test_spec('verify_end_event')
try:
WorkflowService.test_spec(spec_model.id)
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)