From 3086b55b0e96b82a7f5f7a5c488f97ff5ed76420 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Fri, 29 Oct 2010 07:43:56 +0000 Subject: [PATCH] Fixed #14523 -- Modified response handling so that exceptions raised by process_response() in a middleware are caught and handled like any other exception. Thanks to Ivan Sagalaev for the report and patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@14393 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/handlers/base.py | 5 +++++ django/core/handlers/modpython.py | 5 ----- django/core/handlers/wsgi.py | 5 ----- .../middleware_exceptions/tests.py | 21 ++++++++++++++----- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index 109d769d4f..df79ad2029 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -120,6 +120,11 @@ class BaseHandler(object): view_name = callback.__class__.__name__ + '.__call__' # If it's a class raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)) + # Apply response middleware + for middleware_method in self._response_middleware: + response = middleware_method(request, response) + response = self.apply_response_fixes(request, response) + return response except http.Http404, e: logger.warning('Not Found: %s' % request.path, diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py index 5afc61296f..0128f1abe8 100644 --- a/django/core/handlers/modpython.py +++ b/django/core/handlers/modpython.py @@ -215,11 +215,6 @@ class ModPythonHandler(BaseHandler): response = http.HttpResponseBadRequest() else: response = self.get_response(request) - - # Apply response middleware - for middleware_method in self._response_middleware: - response = middleware_method(request, response) - response = self.apply_response_fixes(request, response) finally: signals.request_finished.send(sender=self.__class__) diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index dead1e1adf..36c3c48dbe 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -251,11 +251,6 @@ class WSGIHandler(base.BaseHandler): response = http.HttpResponseBadRequest() else: response = self.get_response(request) - - # Apply response middleware - for middleware_method in self._response_middleware: - response = middleware_method(request, response) - response = self.apply_response_fixes(request, response) finally: signals.request_finished.send(sender=self.__class__) diff --git a/tests/regressiontests/middleware_exceptions/tests.py b/tests/regressiontests/middleware_exceptions/tests.py index 3d9c5f6e83..93c2a89ab3 100644 --- a/tests/regressiontests/middleware_exceptions/tests.py +++ b/tests/regressiontests/middleware_exceptions/tests.py @@ -6,10 +6,14 @@ from django.core.signals import got_request_exception class TestException(Exception): pass -class TestMiddleware(object): +class TestRequestMiddleware(object): def process_request(self, request): raise TestException('Test Exception') +class TestResponseMiddleware(object): + def process_response(self, request, response): + raise TestException('Test Exception') + class MiddlewareExceptionTest(TestCase): def setUp(self): self.exceptions = [] @@ -23,12 +27,11 @@ class MiddlewareExceptionTest(TestCase): def _on_request_exception(self, sender, request, **kwargs): self.exceptions.append(sys.exc_info()) - def test_process_request(self): - self.client.handler._request_middleware.insert(0, TestMiddleware().process_request) + def _assert_exception_handled(self): try: - response = self.client.get('/') + response = self.client.get('/middleware_exceptions/') except TestException, e: - # Test client indefinitely re-raises any exceptions being raised + # Test client intentionally re-raises any exceptions being raised # during request handling. Hence actual testing that exception was # properly handled is done by relying on got_request_exception # signal being sent. @@ -38,3 +41,11 @@ class MiddlewareExceptionTest(TestCase): self.assertEquals(len(self.exceptions), 1) exception, value, tb = self.exceptions[0] self.assertEquals(value.args, ('Test Exception', )) + + def test_process_request(self): + self.client.handler._request_middleware.insert(0, TestRequestMiddleware().process_request) + self._assert_exception_handled() + + def test_process_response(self): + self.client.handler._response_middleware.insert(0, TestResponseMiddleware().process_response) + self._assert_exception_handled()