[CalendarServer-changes] [11491] CalendarServer/branches/users/glyph/hang-fix/twext/web2

source_changes at macosforge.org source_changes at macosforge.org
Fri Jul 5 17:43:38 PDT 2013


Revision: 11491
          http://trac.calendarserver.org//changeset/11491
Author:   glyph at apple.com
Date:     2013-07-05 17:43:38 -0700 (Fri, 05 Jul 2013)
Log Message:
-----------
When processing completely fails, bail out and stop trying to report it to the client; just close the connection.

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/hang-fix/twext/web2/server.py
    CalendarServer/branches/users/glyph/hang-fix/twext/web2/test/test_server.py

Modified: CalendarServer/branches/users/glyph/hang-fix/twext/web2/server.py
===================================================================
--- CalendarServer/branches/users/glyph/hang-fix/twext/web2/server.py	2013-07-06 00:43:36 UTC (rev 11490)
+++ CalendarServer/branches/users/glyph/hang-fix/twext/web2/server.py	2013-07-06 00:43:38 UTC (rev 11491)
@@ -22,12 +22,12 @@
 # SOFTWARE.
 #
 ##
-from __future__ import print_function
 
 """
 This is a web-server which integrates with the twisted.internet
 infrastructure.
 """
+from __future__ import print_function
 
 import cgi, time, urlparse
 from urllib import quote, unquote
@@ -628,18 +628,39 @@
         d.addErrback(self._processingReallyFailed, reason)
         return d
 
+
     def _processingReallyFailed(self, reason, origReason):
+        """
+        An error occurred when attempting to report an error to the HTTP
+        client.
+        """
         log.failure("Exception rendering error page", reason)
         log.failure("Original exception", origReason)
 
-        body = ("<html><head><title>Internal Server Error</title></head>"
-                "<body><h1>Internal Server Error</h1>An error occurred rendering the requested page. Additionally, an error occurred rendering the error page.</body></html>")
+        try:
+            body = (
+                "<html><head><title>Internal Server Error</title></head>"
+                "<body><h1>Internal Server Error</h1>"
+                "An error occurred rendering the requested page. "
+                "Additionally, an error occurred rendering the error page."
+                "</body></html>"
+            )
+            response = http.Response(
+                responsecode.INTERNAL_SERVER_ERROR,
+                {'content-type': http_headers.MimeType('text','html')},
+                body
+            )
+            self.writeResponse(response)
+        except:
+            log.failure(
+                "An error occurred.  We tried to report that error.  "
+                "Reporting that error caused an error.  "
+                "In the process of reporting the error-reporting error to "
+                "the client, there was *yet another* error.  Here it is.  "
+                "I give up."
+            )
+            self.chanRequest.abortConnection()
 
-        response = http.Response(
-            responsecode.INTERNAL_SERVER_ERROR,
-            {'content-type': http_headers.MimeType('text','html')},
-            body)
-        self.writeResponse(response)
 
     def _cbFinishRender(self, result):
         def filterit(response, f):

Modified: CalendarServer/branches/users/glyph/hang-fix/twext/web2/test/test_server.py
===================================================================
--- CalendarServer/branches/users/glyph/hang-fix/twext/web2/test/test_server.py	2013-07-06 00:43:36 UTC (rev 11490)
+++ CalendarServer/branches/users/glyph/hang-fix/twext/web2/test/test_server.py	2013-07-06 00:43:38 UTC (rev 11491)
@@ -171,10 +171,12 @@
         self.finish(failed=True)
 
     def registerProducer(self, producer, streaming):
-        pass
+        if self.producer is not None:
+            raise ValueError("Producer still set: " + repr(self.producer))
+        self.producer = producer
 
     def unregisterProducer(self):
-        pass
+        self.producer = None
 
     def getHostInfo(self):
         return self.hostInfo
@@ -205,7 +207,25 @@
         return stream.MemoryStream(self.responseText)
 
 
+class MyRenderError(Exception):
+    ""
 
+
+class ErrorWithProducerResource(BaseTestResource):
+
+    addSlash = True
+
+    def render(self, req):
+        req.chanRequest.registerProducer(object(), None)
+        return defer.fail(MyRenderError())
+
+
+    def child_(self, request):
+        return self
+
+
+
+
 _unset = object()
 class BaseCase(unittest.TestCase):
     """
@@ -266,7 +286,35 @@
         self.assertEquals(failed, expectedfailure)
 
 
+class ErrorHandlingTest(BaseCase):
+    """
+    Tests for error handling.
+    """
 
+    def test_processingReallyReallyReallyFailed(self):
+        """
+        The HTTP connection will be shut down if there's really no way to relay
+        any useful information about the error to the HTTP client.
+        """
+        root = ErrorWithProducerResource()
+        site = server.Site(root)
+        tcr = TestChanRequest(site, "GET", "/", "http://localhost/")
+        request = server.Request(tcr, "GET", "/", (1, 1),
+                                 0, http_headers.Headers(
+                                        {"host": "localhost"}),
+                                        site=site)
+        proc = request.process()
+        done = []
+        proc.addBoth(done.append)
+        self.assertEquals(done, [None])
+        errs = self.flushLoggedErrors(ValueError)
+        self.assertIn('producer', str(errs[0]).lower())
+        errs = self.flushLoggedErrors(MyRenderError)
+        self.assertEquals(bool(errs), True)
+        self.assertEquals(tcr.finished, True)
+
+
+
 class SampleWebTest(BaseCase):
     class SampleTestResource(BaseTestResource):
         addSlash = True
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130705/07447147/attachment-0001.html>


More information about the calendarserver-changes mailing list