[Checkins] SVN: zope.publisher/trunk/ Don't obscure original exception when handling retries in ``publish.publish()``

Tres Seaver tseaver at palladion.com
Sat Apr 24 16:05:49 EDT 2010


Log message for revision 111391:
  Don't obscure original exception when handling retries in ``publish.publish()``
  
  - Only when ``handleErrors == False``.
  
  - This change makes debugging such exception in unit tests easier.
  
  - Thanks to James Henstridge for the patch.
  
  Fixes LP #209440
  

Changed:
  U   zope.publisher/trunk/CHANGES.txt
  U   zope.publisher/trunk/src/zope/publisher/http.py
  U   zope.publisher/trunk/src/zope/publisher/publish.py
  U   zope.publisher/trunk/src/zope/publisher/tests/test_publisher.py

-=-
Modified: zope.publisher/trunk/CHANGES.txt
===================================================================
--- zope.publisher/trunk/CHANGES.txt	2010-04-24 19:18:28 UTC (rev 111390)
+++ zope.publisher/trunk/CHANGES.txt	2010-04-24 20:05:48 UTC (rev 111391)
@@ -4,12 +4,16 @@
 3.12.3 (unreleased)
 -------------------
 
+- LP #209440: Don't obscure original exception when handling retries
+  in ``publish.publish()`` with ``handleErrors == False``.   This change
+  makes debugging such exception in unit tests easier.
+  Thanks to James Henstridge for the patch.
+
 - LP #98395: allow unicode output of XML content whose mimetype does not
   begin with ``text/``, per RFC 3023 as well as for content types ending
   in ``+xml`` such as Mozilla XUL's ``application/vnd+xml``.  Thanks to
   Justin Ryan for the patch.
 
-
 3.12.2 (2010-04-16)
 -------------------
 

Modified: zope.publisher/trunk/src/zope/publisher/publish.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/publish.py	2010-04-24 19:18:28 UTC (rev 111390)
+++ zope.publisher/trunk/src/zope/publisher/publish.py	2010-04-24 20:05:48 UTC (rev 111391)
@@ -170,7 +170,12 @@
                             retryException.getOriginalException(), False)
                         break
                     else:
-                        raise
+                        to_raise = retryException.getOriginalException()
+                        if to_raise is None:
+                            # There is no original exception inside
+                            # the Retry, so just reraise it.
+                            raise
+                        break
 
             except:
                 # Bad exception handler or retry method.

Modified: zope.publisher/trunk/src/zope/publisher/tests/test_publisher.py
===================================================================
--- zope.publisher/trunk/src/zope/publisher/tests/test_publisher.py	2010-04-24 19:18:28 UTC (rev 111390)
+++ zope.publisher/trunk/src/zope/publisher/tests/test_publisher.py	2010-04-24 20:05:48 UTC (rev 111391)
@@ -22,13 +22,16 @@
 from zope.publisher.base import TestRequest
 from zope.publisher.base import DefaultPublication
 from zope.publisher.interfaces import Unauthorized, NotFound, DebugError
-from zope.publisher.interfaces import IPublication, IReRaiseException
+from zope.publisher.interfaces import IPublication, IReRaiseException, \
+                                      Retry
 
 from zope.interface.verify import verifyClass
 from zope.interface import implementedBy
 
 from StringIO import StringIO
 
+class ErrorToRetry(Exception):
+    """A sample exception that should be retried."""
 
 class PublisherTests(unittest.TestCase):
     def setUp(self):
@@ -47,12 +50,18 @@
             def __call__(self):
                 return "Yo! No docstring!"
 
+        class RetryItem:
+            """An item that the publication will attempt to retry."""
+            def __call__(self):
+                raise ErrorToRetry()
+
         self.app = AppRoot()
         self.app.folder = Folder()
         self.app.folder.item = Item()
 
         self.app._item = Item()
         self.app.noDocString = NoDocstringItem()
+        self.app.retryItem = RetryItem()
 
     def _createRequest(self, path, **kw):
         publication = DefaultPublication(self.app)
@@ -128,7 +137,36 @@
             pass
         self._unregisterExcAdapter(doReRaiseAdapter)
         self.failUnlessEqual(raised, True)
-            
+
+    def testRetryErrorIsUnwrapped(self):
+        test = self
+        class RetryPublication(DefaultPublication):
+            def handleException(self, object, request, exc_info,
+                                retry_allowed=True):
+                test.assertTrue(issubclass(exc_info[0], ErrorToRetry))
+                raise Retry(exc_info)
+
+        request = self._createRequest('/retryItem')
+        request.setPublication(RetryPublication(self.app))
+        self.assertFalse(request.supportsRetry())
+        self.assertRaises(ErrorToRetry, publish, request, handle_errors=False)
+
+    def testBareRetryErrorPassedThrough(self):
+        test = self
+        class RetryPublication(DefaultPublication):
+            def handleException(self, object, request, exc_info,
+                                retry_allowed=True):
+                test.assertTrue(issubclass(exc_info[0], ErrorToRetry))
+                raise Retry()
+
+        request = self._createRequest('/retryItem')
+        request.setPublication(RetryPublication(self.app))
+        self.assertFalse(request.supportsRetry())
+        # Retry exception is passed through because it doesn't contain
+        # an original exception.
+        self.assertRaises(Retry, publish, request, handle_errors=False)
+
+
 def test_suite():
     loader = unittest.TestLoader()
     return loader.loadTestsFromTestCase(PublisherTests)



More information about the checkins mailing list