From 9c70043fb07f126fe1f05cba9a6ebae914bafb0c Mon Sep 17 00:00:00 2001 From: Thomas NOEL Date: Tue, 19 Jun 2018 15:04:19 +0200 Subject: [PATCH] wf/backoffice_fields: only log condition errors as functional errors (#24645) --- tests/test_workflows.py | 30 ++++++++++++++++++++++++++++++ wcs/wf/backoffice_fields.py | 17 +++++++++++++---- wcs/workflows.py | 19 ++++++++++++++++--- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/tests/test_workflows.py b/tests/test_workflows.py index e6f187ae..7919bce4 100644 --- a/tests/test_workflows.py +++ b/tests/test_workflows.py @@ -3014,6 +3014,25 @@ 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.startswith('Failed to evaluate Python expression') + assert logged_error.formdata_id == str(formdata.id) + + 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.startswith('Failed to evaluate template') + assert logged_error.formdata_id == str(formdata.id) + def test_set_backoffice_field_file(http_requests, two_pubs): Workflow.wipe() FormDef.wipe() @@ -3135,14 +3154,21 @@ 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) else: # empty value : remove field assert formdata.data['bo1'] is None + assert LoggedError.count() == 0 # check wrong field item = SetBackofficeFieldsWorkflowStatusItem() @@ -3353,14 +3379,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() diff --git a/wcs/wf/backoffice_fields.py b/wcs/wf/backoffice_fields.py index 2ed97abe..cf973621 100644 --- a/wcs/wf/backoffice_fields.py +++ b/wcs/wf/backoffice_fields.py @@ -97,16 +97,25 @@ 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 %(result)r (%(class)s computed from %(value)s) ' + 'to a %(kind)s field (%(id)s)') % { + 'result': new_value, + 'class': new_value.__class__.__name__, + 'value': field['value'], + 'kind': getattr(formdef_field, 'key', 'unknown'), + 'id': field['field_id'], + } + LoggedError.record(summary, formdata=formdata, status_item=self) continue formdata.data['%s' % field['field_id']] = new_value diff --git a/wcs/workflows.py b/wcs/workflows.py index 52d13285..a9fa8dac 100644 --- a/wcs/workflows.py +++ b/wcs/workflows.py @@ -1677,7 +1677,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, formdata=None, status_item=None, context=None): if not isinstance(var, basestring): return var @@ -1692,17 +1692,30 @@ class WorkflowStatusItem(XmlSerialisable): vars = get_publisher().substitutions.get_context_variables() vars.update(context or {}) + def log_error(message): + from wcs.logged_errors import LoggedError + summary = _('Failed to evaluate %(type)s "%(value)s": %(message)s') % { + 'type': {'text': _('text'), + 'template': _('template'), + 'python': _('Python expression')}.get(expression['type']), + 'value': expression['value'], + 'message': message + } + LoggedError.record(summary, formdata=formdata, status_item=status_item) + if expression['type'] == 'template': try: return Template(expression['value'], raises=raises, autoescape=False).render(vars) - except TemplateError: + except TemplateError as e: + log_error(str(e)) if raises: raise return var try: return eval(expression['value'], get_publisher().get_global_eval_dict(), vars) - except: + except Exception as e: + log_error(str(e)) if raises: raise return var -- 2.17.1