# HG changeset patch # User Thierry Florac # Date 1507878326 -7200 # Node ID 397c6a04210647a1de7e3e5e66cd855261b9e12f # Parent 9c2648bc7076eeba51b9920890dd4a68bfadfd3b Added ValidationError exception management diff -r 9c2648bc7076 -r 397c6a042106 src/pyams_form/form.py --- a/src/pyams_form/form.py Fri Oct 13 09:02:41 2017 +0200 +++ b/src/pyams_form/form.py Fri Oct 13 09:05:26 2017 +0200 @@ -30,6 +30,7 @@ from pyramid_chameleon.interfaces import IChameleonTranslate from z3c.form.interfaces import DISPLAY_MODE, IErrorViewSnippet, IMultipleErrors from zope.publisher.interfaces.browser import IBrowserRequest +from zope.schema.interfaces import ValidationError # import packages from pyams_form.group import GroupsBasedForm @@ -247,13 +248,13 @@ def get_ajax_handler(self): return absolute_url(self.context, self.request, self.ajax_handler) - def get_ajax_errors(self): + def get_ajax_errors(self, ajax_errors=None): """Extract form errors in AJAX format""" translate = self.request.localizer.translate errors = {'status': u'error', 'error_message': translate(self.status)} registry = self.request.registry - for error in self.errors: + for error in (ajax_errors or self.errors): if isinstance(error, Exception): error = registry.getMultiAdapter((error, self.request, None, None, self, self.request), IErrorViewSnippet) @@ -352,8 +353,20 @@ errors = errors + form_errors if errors or self.errors: return self.get_ajax_errors() - result = self.createAndAdd(data) - return self.get_ajax_output(result) + try: + result = self.createAndAdd(data) + except ValidationError as error: + # This error can occur with file-type inputs + registry = self.request.registry + widget = self.widgets[error.args[-1]] + view = registry.getMultiAdapter((error, self.request, widget, widget.field, self, self.context), + IErrorViewSnippet) + view.update() + widget.error = view + errors = (view,) + return self.get_ajax_errors(errors) + else: + return self.get_ajax_output(result) def get_ajax_output(self, changes): output = {} @@ -448,28 +461,40 @@ if errors or self.errors: return self.get_ajax_errors() # update form content - changes = {} - for form in self.forms: - if form.mode == DISPLAY_MODE: - continue - changes.update(form.applyChanges(data) or {}) - # check JSON output - output = self.get_ajax_output(changes) - translate = self.request.localizer.translate - status = output.get('status') - message = output.get('message') - if not changes: - if not status: - output['status'] = 'info' - if not message: - output['message'] = translate(self.noChangesMessage) + try: + changes = {} + for form in self.forms: + if form.mode == DISPLAY_MODE: + continue + changes.update(form.applyChanges(data) or {}) + except ValidationError as error: + # This error can occur with file-type inputs + registry = self.request.registry + widget = self.widgets[error.args[-1]] + view = registry.getMultiAdapter((error, self.request, widget, widget.field, self, self.context), + IErrorViewSnippet) + view.update() + widget.error = view + errors = (view,) + return self.get_ajax_errors(errors) else: - if not status: - output['status'] = status = 'success' - if not message: - if status == 'success': - output['message'] = translate(self.successMessage) - return output + # check JSON output + output = self.get_ajax_output(changes) + translate = self.request.localizer.translate + status = output.get('status') + message = output.get('message') + if not changes: + if not status: + output['status'] = 'info' + if not message: + output['message'] = translate(self.noChangesMessage) + else: + if not status: + output['status'] = status = 'success' + if not message: + if status == 'success': + output['message'] = translate(self.successMessage) + return output def get_ajax_output(self, changes): output = {}