0001-wf-backoffice_fields-log-compute-errors-as-functiona.patch
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 |
- |