Projet

Général

Profil

0001-wf-backoffice_fields-log-compute-errors-as-functiona.patch

Thomas Noël, 06 juillet 2018 15:24

Télécharger (8,34 ko)

Voir les différences:

Subject: [PATCH] wf/backoffice_fields: log compute errors as functional errors
 only (#24645)

 tests/test_workflows.py     | 41 +++++++++++++++++++++++++++++++++++++
 wcs/wf/backoffice_fields.py | 18 ++++++++++++----
 wcs/workflows.py            | 19 ++++++++++++++---
 3 files changed, 71 insertions(+), 7 deletions(-)
tests/test_workflows.py
2975 2975
def test_set_backoffice_field(http_requests, two_pubs):
2976 2976
    Workflow.wipe()
2977 2977
    FormDef.wipe()
2978
    LoggedError.wipe()
2978 2979
    wf = Workflow(name='xxx')
2979 2980
    wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
2980 2981
    wf.backoffice_fields_formdef.fields = [
......
3020 3021
    formdata = formdef.data_class().get(formdata.id)
3021 3022
    assert formdata.data['bo1'] == 'HELLO GOODBYE'
3022 3023

  
3024
    assert LoggedError.count() == 0
3025

  
3026
    item.fields = [{'field_id': 'bo1', 'value': '= ~ invalid python ~'}]
3027
    item.perform(formdata)
3028
    formdata = formdef.data_class().get(formdata.id)
3029
    assert LoggedError.count() == 1
3030
    logged_error = LoggedError.select()[0]
3031
    assert logged_error.summary == 'Failed to compute Python Expression'
3032
    assert logged_error.formdata_id == str(formdata.id)
3033
    assert logged_error.expression == ' ~ invalid python ~'
3034
    assert logged_error.expression_type == 'python'
3035
    assert logged_error.exception_class == 'SyntaxError'
3036
    assert logged_error.exception_message == 'invalid syntax (<string>, line 1)'
3037

  
3038
    LoggedError.wipe()
3039
    item.fields = [{'field_id': 'bo1', 'value': '{% if bad django %}'}]
3040
    item.perform(formdata)
3041
    formdata = formdef.data_class().get(formdata.id)
3042
    assert LoggedError.count() == 1
3043
    logged_error = LoggedError.select()[0]
3044
    assert logged_error.summary == 'Failed to compute Template'
3045
    assert logged_error.formdata_id == str(formdata.id)
3046
    assert logged_error.expression == '{% if bad django %}'
3047
    assert logged_error.expression_type == 'template'
3048
    assert logged_error.exception_class == 'TemplateError'
3049
    assert logged_error.exception_message.startswith('syntax error in Django template')
3050

  
3023 3051
def test_set_backoffice_field_file(http_requests, two_pubs):
3024 3052
    Workflow.wipe()
3025 3053
    FormDef.wipe()
......
3141 3169
        item = SetBackofficeFieldsWorkflowStatusItem()
3142 3170
        item.parent = st1
3143 3171
        item.fields = [{'field_id': 'bo1', 'value': value}]
3172

  
3173
        LoggedError.wipe()
3144 3174
        item.perform(formdata)
3145 3175

  
3146 3176
        formdata = formdef.data_class().get(formdata.id)
3147 3177
        if value is not None:  # wrong value : do nothing
3148 3178
            assert formdata.data['bo1'].base_filename == 'hello.txt'
3149 3179
            assert formdata.data['bo1'].get_content() == 'HELLO WORLD'
3180
            assert LoggedError.count() == 1
3181
            logged_error = LoggedError.select()[0]
3182
            assert logged_error.summary.startswith('Failed to convert')
3183
            assert logged_error.formdata_id == str(formdata.id)
3184
            assert logged_error.exception_class == 'ValueError'
3150 3185
        else:  # empty value : remove field
3151 3186
            assert formdata.data['bo1'] is None
3187
            assert LoggedError.count() == 0
3152 3188

  
3153 3189
    # check wrong field
3154 3190
    item = SetBackofficeFieldsWorkflowStatusItem()
......
3312 3348
def test_set_backoffice_field_date(two_pubs):
3313 3349
    Workflow.wipe()
3314 3350
    FormDef.wipe()
3351
    LoggedError.wipe()
3315 3352
    wf = Workflow(name='xxx')
3316 3353
    wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
3317 3354
    st1 = wf.add_status('Status1')
......
3359 3396
    assert datetime.date(*formdata.data['bo1'][:3]) == datetime.date(2017, 3, 23)
3360 3397

  
3361 3398
    # invalid values => do nothing
3399
    assert LoggedError.count() == 0
3362 3400
    for value in ('plop', {}, []):
3363 3401
        item = SetBackofficeFieldsWorkflowStatusItem()
3364 3402
        item.parent = st1
3365 3403
        item.fields = [{'field_id': 'bo1', 'value': value}]
3366 3404

  
3405
        LoggedError.wipe()
3367 3406
        item.perform(formdata)
3368 3407
        formdata = formdef.data_class().get(formdata.id)
3369 3408
        assert datetime.date(*formdata.data['bo1'][:3]) == datetime.date(2017, 3, 23)
3409
        assert LoggedError.count() == 1
3410
        assert LoggedError.select()[0].summary.startswith('Failed to convert')
3370 3411

  
3371 3412
    # None : empty date
3372 3413
    item = SetBackofficeFieldsWorkflowStatusItem()
wcs/wf/backoffice_fields.py
97 97
                continue
98 98

  
99 99
            try:
100
                new_value = self.compute(field['value'], raises=True)
100
                new_value = self.compute(field['value'], raises=True,
101
                                         formdata=formdata, status_item=self)
101 102
            except:
102
                get_publisher().notify_of_exception(sys.exc_info(), context='[BO_FIELDS]')
103 103
                continue
104 104

  
105 105
            if formdef_field.convert_value_from_anything:
106 106
                try:
107 107
                    new_value = formdef_field.convert_value_from_anything(new_value)
108
                except ValueError:
109
                    get_publisher().notify_of_exception(sys.exc_info(), context='[BO_FIELDS]')
108
                except ValueError as e:
109
                    from wcs.logged_errors import LoggedError
110
                    summary = _('Failed to convert %(class)s value to %(kind)s field (%(id)s)') % {
111
                                    'class': type(new_value),
112
                                    'kind': _(getattr(formdef_field, 'description', 'unknown')),
113
                                    'id': field['field_id'],
114
                                }
115
                    expression_dict = self.get_expression(field['value'])
116
                    LoggedError.record(summary, formdata=formdata, status_item=self,
117
                                       expression=expression_dict['value'],
118
                                       expression_type=expression_dict['type'],
119
                                       exception=e)
110 120
                    continue
111 121

  
112 122
            formdata.data['%s' % field['field_id']] = new_value
wcs/workflows.py
1680 1680
        return {'type': expression_type, 'value': expression_value}
1681 1681

  
1682 1682
    @classmethod
1683
    def compute(cls, var, render=True, raises=False, context=None):
1683
    def compute(cls, var, render=True, raises=False, context=None, formdata=None, status_item=None):
1684 1684
        if not isinstance(var, basestring):
1685 1685
            return var
1686 1686

  
......
1695 1695
        vars = get_publisher().substitutions.get_context_variables()
1696 1696
        vars.update(context or {})
1697 1697

  
1698
        def log_exception(exception):
1699
            from wcs.logged_errors import LoggedError
1700
            if expression['type'] == 'template':
1701
                summary = _('Failed to compute Template')
1702
            else:
1703
                summary = _('Failed to compute Python Expression')
1704
            LoggedError.record(summary, formdata=formdata, status_item=status_item,
1705
                               expression=expression['value'],
1706
                               expression_type=expression['type'],
1707
                               exception=exception)
1708

  
1698 1709
        if expression['type'] == 'template':
1699 1710
            try:
1700 1711
                return Template(expression['value'], raises=raises, autoescape=False).render(vars)
1701
            except TemplateError:
1712
            except TemplateError as e:
1713
                log_exception(e)
1702 1714
                if raises:
1703 1715
                    raise
1704 1716
                return var
1705 1717

  
1706 1718
        try:
1707 1719
            return eval(expression['value'], get_publisher().get_global_eval_dict(), vars)
1708
        except:
1720
        except Exception as e:
1721
            log_exception(e)
1709 1722
            if raises:
1710 1723
                raise
1711 1724
            return var
1712
-