[Zope3-checkins] SVN: Zope3/trunk/ - Improve error handling in formlib:

Roger Ineichen roger at projekt01.ch
Tue May 16 18:22:01 EDT 2006


Log message for revision 68157:
  - Improve error handling in formlib:
    Fix invariant error handling in formlib. The exception Invalid raised 
    in interface invariants where end in a component lookup error because
    this exception didn't get converted to a usefull error message.
    Now the error_views method in formlib can handle strings and i18n 
    Message based Invalid exceptions.
  - Added test for Invalid exceptions handling
  - Added also a small fix which makes sure that existing errors
    from master/subforms don't get overriden by calling update in 
    FormBase.
  - Added note in Changes.txt

Changed:
  U   Zope3/trunk/doc/CHANGES.txt
  U   Zope3/trunk/src/zope/formlib/form.py
  U   Zope3/trunk/src/zope/formlib/tests.py

-=-
Modified: Zope3/trunk/doc/CHANGES.txt
===================================================================
--- Zope3/trunk/doc/CHANGES.txt	2006-05-16 19:40:59 UTC (rev 68156)
+++ Zope3/trunk/doc/CHANGES.txt	2006-05-16 22:22:00 UTC (rev 68157)
@@ -128,6 +128,12 @@
 
     Bug Fixes
 
+      - Fix invariant error handling in formlib. The exception Invalid raised
+        in interface invariants where end in a component lookup error because
+        this exception didn't get converted to a usefull error message.
+        Now the error_views method in formlib can handle strings and i18n 
+        Message based Invalid exceptions.
+
       - Fixed error handling in sequence item input widget. This widget
         was raising a ValidationError instead a WidgetInputError. The formlib
         didn't catch ValidationErrors. Added also ValidationError handling to

Modified: Zope3/trunk/src/zope/formlib/form.py
===================================================================
--- Zope3/trunk/src/zope/formlib/form.py	2006-05-16 19:40:59 UTC (rev 68156)
+++ Zope3/trunk/src/zope/formlib/form.py	2006-05-16 22:22:00 UTC (rev 68157)
@@ -717,7 +717,13 @@
 
         data = {}
         errors, action = handleSubmit(self.actions, data, self.validate)
-        self.errors = errors
+        # the following part will make sure that previous error not
+        # get overriden by new errors. This is usefull for subforms. (ri)
+        if self.errors is None:
+            self.errors = errors
+        else:
+            if errors is not None:
+                self.errors += tuple(errors)
 
         if errors:
             self.status = _('There were errors')
@@ -750,6 +756,14 @@
         for error in self.errors:
             if isinstance(error, basestring):
                 yield error
+            elif isinstance(error, interface.Invalid):
+                # convert invariants Invalid exception into usefull error
+                # message strings rather then end in component lookup error
+                msg = error.args[0]
+                if isinstance(msg, zope.i18n.Message):
+                    msg = zope.i18n.translate(msg, context=self.request, 
+                        default=msg)
+                yield u'<span class="error">%s</span>' % msg
             else:
                 view = component.getMultiAdapter(
                     (error, self.request),

Modified: Zope3/trunk/src/zope/formlib/tests.py
===================================================================
--- Zope3/trunk/src/zope/formlib/tests.py	2006-05-16 19:40:59 UTC (rev 68156)
+++ Zope3/trunk/src/zope/formlib/tests.py	2006-05-16 22:22:00 UTC (rev 68157)
@@ -309,6 +309,48 @@
 """
 
 
+def test_invariants():
+    """\
+
+Let's also test the invariant error handling. Interface invariant methods 
+raise zope.schem.Invalid exception. Test if this exception get handled by the 
+error_views.
+
+    >>> from zope.interface import Invalid
+    >>> myError = Invalid('My error message')
+    >>> from zope.publisher.browser import TestRequest
+    >>> req = TestRequest()
+    >>> mybase = form.FormBase(None, req)
+    >>> mybase.errors = (myError,)
+    >>> save = mybase.error_views()
+    >>> save.next()
+    u'<span class="error">My error message</span>'
+
+And yes, we can even handle a i18n message in a Invalid exception:
+
+    >>> from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
+    >>> from zope.i18n.interfaces import ITranslationDomain
+    >>> messageDic = {('ja', u'My i18n error message'): u'Mein Fehler'}
+    >>> sd = SimpleTranslationDomain('foobar.domain', messageDic)
+    >>> component.provideUtility(provides=ITranslationDomain,
+    ...                          component=sd,
+    ...                          name='foobar.domain')
+    >>> from zope.i18n.negotiator import negotiator
+    >>> component.provideUtility(negotiator)
+    >>> _ = zope.i18nmessageid.MessageFactory('foobar.domain')
+    >>> myError = Invalid(_('My i18n error message'))
+    >>> from zope.publisher.browser import TestRequest
+    >>> req = TestRequest()
+    >>> req._environ['HTTP_ACCEPT_LANGUAGE'] = 'ja; q=1.0'
+    >>> mybase = form.FormBase(None, req)
+    >>> mybase.errors = (myError,)
+    >>> save = mybase.error_views()
+    >>> save.next()
+    u'<span class="error">Mein Fehler</span>'
+
+"""
+
+
 def test_form_template_i18n():
     """\
 Let's try to check that the formlib templates handle i18n correctly.



More information about the Zope3-Checkins mailing list