[Zope3-checkins] SVN: Zope3/branches/3.3/ backported bugfix from trunk (r68157):

Yvo Schubbe y.2006_ at wcm-solutions.de
Thu Sep 28 18:00:07 EDT 2006


Log message for revision 70430:
  backported bugfix from trunk (r68157):
  
  - 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/branches/3.3/doc/CHANGES.txt
  U   Zope3/branches/3.3/src/zope/formlib/form.py
  U   Zope3/branches/3.3/src/zope/formlib/tests.py

-=-
Modified: Zope3/branches/3.3/doc/CHANGES.txt
===================================================================
--- Zope3/branches/3.3/doc/CHANGES.txt	2006-09-28 21:04:47 UTC (rev 70429)
+++ Zope3/branches/3.3/doc/CHANGES.txt	2006-09-28 22:00:05 UTC (rev 70430)
@@ -10,6 +10,12 @@
 
     Bugfixes
 
+      - 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 a bug in getImageInfo which could cause an
         UnboundLocalError under certain conditions.
   

Modified: Zope3/branches/3.3/src/zope/formlib/form.py
===================================================================
--- Zope3/branches/3.3/src/zope/formlib/form.py	2006-09-28 21:04:47 UTC (rev 70429)
+++ Zope3/branches/3.3/src/zope/formlib/form.py	2006-09-28 22:00:05 UTC (rev 70430)
@@ -722,7 +722,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')
@@ -755,6 +761,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/branches/3.3/src/zope/formlib/tests.py
===================================================================
--- Zope3/branches/3.3/src/zope/formlib/tests.py	2006-09-28 21:04:47 UTC (rev 70429)
+++ Zope3/branches/3.3/src/zope/formlib/tests.py	2006-09-28 22:00:05 UTC (rev 70430)
@@ -316,6 +316,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