]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Don't try sending another error response in _handle_request_exception
authorBen Darnell <ben@bendarnell.com>
Sun, 12 May 2013 23:32:20 +0000 (19:32 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 12 May 2013 23:32:54 +0000 (19:32 -0400)
if the stack context catches an error after the request is done.

(this may be related to the error discussed in the comments of #751)

tornado/test/web_test.py
tornado/web.py

index a7f89620dc71dfed99cd31c7a3a3430ccac306ca..5e813e5d0ab0b320522b28b1395469117e53431c 100644 (file)
@@ -1250,3 +1250,31 @@ class GetArgumentErrorTest(SimpleHandlerTestCase):
         self.assertEqual(json_decode(response.body),
                          {'arg_name': 'foo',
                           'log_message': 'Missing argument foo'})
+
+
+class MultipleExceptionTest(SimpleHandlerTestCase):
+    class Handler(RequestHandler):
+        exc_count = 0
+
+        @asynchronous
+        def get(self):
+            from tornado.ioloop import IOLoop
+            IOLoop.current().add_callback(lambda: 1 / 0)
+            IOLoop.current().add_callback(lambda: 1 / 0)
+
+        def log_exception(self, typ, value, tb):
+            MultipleExceptionTest.Handler.exc_count += 1
+
+    def test_multi_exception(self):
+        # This test verifies that multiple exceptions raised into the same
+        # ExceptionStackContext do not generate extraneous log entries
+        # due to "Cannot send error response after headers written".
+        # log_exception is called, but it does not proceed to send_error.
+        response = self.fetch('/')
+        self.assertEqual(response.code, 500)
+        response = self.fetch('/')
+        self.assertEqual(response.code, 500)
+        # Each of our two requests generated two exceptions, we should have
+        # seen at least three of them by now (the fourth may still be
+        # in the queue).
+        self.assertGreater(MultipleExceptionTest.Handler.exc_count, 2)
index 7bc715d7e5835539a0c9432e7659af5a7ad94ccd..dfa357c002cae33e2c0677067d825d6710ffae9d 100644 (file)
@@ -1113,6 +1113,11 @@ class RequestHandler(object):
 
     def _handle_request_exception(self, e):
         self.log_exception(*sys.exc_info())
+        if self._finished:
+            # Extra errors after the request has been finished should
+            # be logged, but there is no reason to continue to try and
+            # send a response.
+            return
         if isinstance(e, HTTPError):
             if e.status_code not in httputil.responses and not e.reason:
                 gen_log.error("Bad HTTP status code: %d", e.status_code)