wf/backoffice_fields: log compute errors as functional errors only (#24645)

This commit is contained in:
Thomas NOËL 2018-06-19 15:04:19 +02:00
parent b0ff2e4575
commit 7d2e14a1f2
3 changed files with 71 additions and 7 deletions

View File

@ -2975,6 +2975,7 @@ def test_profile(two_pubs):
def test_set_backoffice_field(http_requests, two_pubs):
Workflow.wipe()
FormDef.wipe()
LoggedError.wipe()
wf = Workflow(name='xxx')
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
wf.backoffice_fields_formdef.fields = [
@ -3020,6 +3021,33 @@ def test_set_backoffice_field(http_requests, two_pubs):
formdata = formdef.data_class().get(formdata.id)
assert formdata.data['bo1'] == 'HELLO GOODBYE'
assert LoggedError.count() == 0
item.fields = [{'field_id': 'bo1', 'value': '= ~ invalid python ~'}]
item.perform(formdata)
formdata = formdef.data_class().get(formdata.id)
assert LoggedError.count() == 1
logged_error = LoggedError.select()[0]
assert logged_error.summary == 'Failed to compute Python expression'
assert logged_error.formdata_id == str(formdata.id)
assert logged_error.expression == ' ~ invalid python ~'
assert logged_error.expression_type == 'python'
assert logged_error.exception_class == 'SyntaxError'
assert logged_error.exception_message == 'invalid syntax (<string>, line 1)'
LoggedError.wipe()
item.fields = [{'field_id': 'bo1', 'value': '{% if bad django %}'}]
item.perform(formdata)
formdata = formdef.data_class().get(formdata.id)
assert LoggedError.count() == 1
logged_error = LoggedError.select()[0]
assert logged_error.summary == 'Failed to compute template'
assert logged_error.formdata_id == str(formdata.id)
assert logged_error.expression == '{% if bad django %}'
assert logged_error.expression_type == 'template'
assert logged_error.exception_class == 'TemplateError'
assert logged_error.exception_message.startswith('syntax error in Django template')
def test_set_backoffice_field_file(http_requests, two_pubs):
Workflow.wipe()
FormDef.wipe()
@ -3141,14 +3169,22 @@ def test_set_backoffice_field_file(http_requests, two_pubs):
item = SetBackofficeFieldsWorkflowStatusItem()
item.parent = st1
item.fields = [{'field_id': 'bo1', 'value': value}]
LoggedError.wipe()
item.perform(formdata)
formdata = formdef.data_class().get(formdata.id)
if value is not None: # wrong value : do nothing
assert formdata.data['bo1'].base_filename == 'hello.txt'
assert formdata.data['bo1'].get_content() == 'HELLO WORLD'
assert LoggedError.count() == 1
logged_error = LoggedError.select()[0]
assert logged_error.summary.startswith('Failed to convert')
assert logged_error.formdata_id == str(formdata.id)
assert logged_error.exception_class == 'ValueError'
else: # empty value : remove field
assert formdata.data['bo1'] is None
assert LoggedError.count() == 0
# check wrong field
item = SetBackofficeFieldsWorkflowStatusItem()
@ -3312,6 +3348,7 @@ def test_set_backoffice_field_items(two_pubs):
def test_set_backoffice_field_date(two_pubs):
Workflow.wipe()
FormDef.wipe()
LoggedError.wipe()
wf = Workflow(name='xxx')
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
st1 = wf.add_status('Status1')
@ -3359,14 +3396,18 @@ def test_set_backoffice_field_date(two_pubs):
assert datetime.date(*formdata.data['bo1'][:3]) == datetime.date(2017, 3, 23)
# invalid values => do nothing
assert LoggedError.count() == 0
for value in ('plop', {}, []):
item = SetBackofficeFieldsWorkflowStatusItem()
item.parent = st1
item.fields = [{'field_id': 'bo1', 'value': value}]
LoggedError.wipe()
item.perform(formdata)
formdata = formdef.data_class().get(formdata.id)
assert datetime.date(*formdata.data['bo1'][:3]) == datetime.date(2017, 3, 23)
assert LoggedError.count() == 1
assert LoggedError.select()[0].summary.startswith('Failed to convert')
# None : empty date
item = SetBackofficeFieldsWorkflowStatusItem()

View File

@ -97,16 +97,26 @@ class SetBackofficeFieldsWorkflowStatusItem(WorkflowStatusItem):
continue
try:
new_value = self.compute(field['value'], raises=True)
new_value = self.compute(field['value'], raises=True,
formdata=formdata, status_item=self)
except:
get_publisher().notify_of_exception(sys.exc_info(), context='[BO_FIELDS]')
continue
if formdef_field.convert_value_from_anything:
try:
new_value = formdef_field.convert_value_from_anything(new_value)
except ValueError:
get_publisher().notify_of_exception(sys.exc_info(), context='[BO_FIELDS]')
except ValueError as e:
from wcs.logged_errors import LoggedError
summary = _('Failed to convert %(class)s value to %(kind)s field (%(id)s)') % {
'class': type(new_value),
'kind': _(getattr(formdef_field, 'description', 'unknown')),
'id': field['field_id'],
}
expression_dict = self.get_expression(field['value'])
LoggedError.record(summary, formdata=formdata, status_item=self,
expression=expression_dict['value'],
expression_type=expression_dict['type'],
exception=e)
continue
formdata.data['%s' % field['field_id']] = new_value

View File

@ -1680,7 +1680,7 @@ class WorkflowStatusItem(XmlSerialisable):
return {'type': expression_type, 'value': expression_value}
@classmethod
def compute(cls, var, render=True, raises=False, context=None):
def compute(cls, var, render=True, raises=False, context=None, formdata=None, status_item=None):
if not isinstance(var, basestring):
return var
@ -1695,17 +1695,30 @@ class WorkflowStatusItem(XmlSerialisable):
vars = get_publisher().substitutions.get_context_variables()
vars.update(context or {})
def log_exception(exception):
from wcs.logged_errors import LoggedError
if expression['type'] == 'template':
summary = _('Failed to compute template')
else:
summary = _('Failed to compute Python expression')
LoggedError.record(summary, formdata=formdata, status_item=status_item,
expression=expression['value'],
expression_type=expression['type'],
exception=exception)
if expression['type'] == 'template':
try:
return Template(expression['value'], raises=raises, autoescape=False).render(vars)
except TemplateError:
except TemplateError as e:
log_exception(e)
if raises:
raise
return var
try:
return eval(expression['value'], get_publisher().get_global_eval_dict(), vars)
except:
except Exception as e:
log_exception(e)
if raises:
raise
return var