Added ValidationError exception management
authorThierry Florac <thierry.florac@onf.fr>
Fri, 13 Oct 2017 09:05:26 +0200
changeset 68 397c6a042106
parent 67 9c2648bc7076
child 69 0df6b07cf813
Added ValidationError exception management
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 = {}