Loading django/core/handlers/base.py +17 −10 Original line number Diff line number Diff line Loading @@ -146,15 +146,7 @@ class BaseHandler(object): try: response = wrapped_callback(request, *callback_args, **callback_kwargs) except Exception as e: # If the view raised an exception, run it through exception # middleware, and if the exception middleware returns a # response, use that. Otherwise, reraise the exception. for middleware_method in self._exception_middleware: response = middleware_method(request, e) if response: break if response is None: raise response = self.process_exception_by_middleware(e, request) # Complain if the view returned None (a common error). if response is None: Loading @@ -176,7 +168,11 @@ class BaseHandler(object): "%s.process_template_response didn't return an " "HttpResponse object. It returned None instead." % (middleware_method.__self__.__class__.__name__)) try: response = response.render() except Exception as e: response = self.process_exception_by_middleware(e, request) response_is_rendered = True except http.Http404 as exc: Loading Loading @@ -257,6 +253,17 @@ class BaseHandler(object): return response def process_exception_by_middleware(self, exception, request): """ Pass the exception to the exception middleware. If no middleware return a response for this exception, raise it. """ for middleware_method in self._exception_middleware: response = middleware_method(request, exception) if response: return response raise def handle_uncaught_exception(self, request, resolver, exc_info): """ Processing for any otherwise uncaught exceptions (those that will Loading docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,9 @@ Requests and Responses :class:`~django.template.response.TemplateResponse`, commonly used with class-based views. * Exceptions raised by the ``render()`` method are now passed to the ``process_exception()`` method of each middleware. * Request middleware can now set :attr:`HttpRequest.urlconf <django.http.HttpRequest.urlconf>` to ``None`` to revert any changes made by previous middleware and return to using the :setting:`ROOT_URLCONF`. Loading tests/middleware_exceptions/middleware.py 0 → 100644 +8 −0 Original line number Diff line number Diff line from __future__ import unicode_literals from django.http import HttpResponse class ProcessExceptionMiddleware(object): def process_exception(self, request, exception): return HttpResponse('Exception caught') tests/middleware_exceptions/tests.py +10 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,16 @@ class MiddlewareTests(BaseMiddlewareExceptionTest): # Check that the right middleware methods have been invoked self.assert_middleware_usage(middleware, True, True, True, True, False) @override_settings( MIDDLEWARE_CLASSES=['middleware_exceptions.middleware.ProcessExceptionMiddleware'], ) def test_exception_in_render_passed_to_process_exception(self): # Repopulate the list of middlewares since it's already been populated # by setUp() before the MIDDLEWARE_CLASSES setting got overridden self.client.handler.load_middleware() response = self.client.get('/middleware_exceptions/exception_in_render/') self.assertEqual(response.content, b'Exception caught') class BadMiddlewareTests(BaseMiddlewareExceptionTest): Loading tests/middleware_exceptions/urls.py +1 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ urlpatterns = [ url(r'^middleware_exceptions/error/$', views.server_error), url(r'^middleware_exceptions/null_view/$', views.null_view), url(r'^middleware_exceptions/permission_denied/$', views.permission_denied), url(r'^middleware_exceptions/exception_in_render/$', views.exception_in_render), url(r'^middleware_exceptions/template_response/$', views.template_response), url(r'^middleware_exceptions/template_response_error/$', views.template_response_error), Loading Loading
django/core/handlers/base.py +17 −10 Original line number Diff line number Diff line Loading @@ -146,15 +146,7 @@ class BaseHandler(object): try: response = wrapped_callback(request, *callback_args, **callback_kwargs) except Exception as e: # If the view raised an exception, run it through exception # middleware, and if the exception middleware returns a # response, use that. Otherwise, reraise the exception. for middleware_method in self._exception_middleware: response = middleware_method(request, e) if response: break if response is None: raise response = self.process_exception_by_middleware(e, request) # Complain if the view returned None (a common error). if response is None: Loading @@ -176,7 +168,11 @@ class BaseHandler(object): "%s.process_template_response didn't return an " "HttpResponse object. It returned None instead." % (middleware_method.__self__.__class__.__name__)) try: response = response.render() except Exception as e: response = self.process_exception_by_middleware(e, request) response_is_rendered = True except http.Http404 as exc: Loading Loading @@ -257,6 +253,17 @@ class BaseHandler(object): return response def process_exception_by_middleware(self, exception, request): """ Pass the exception to the exception middleware. If no middleware return a response for this exception, raise it. """ for middleware_method in self._exception_middleware: response = middleware_method(request, exception) if response: return response raise def handle_uncaught_exception(self, request, resolver, exc_info): """ Processing for any otherwise uncaught exceptions (those that will Loading
docs/releases/1.9.txt +3 −0 Original line number Diff line number Diff line Loading @@ -480,6 +480,9 @@ Requests and Responses :class:`~django.template.response.TemplateResponse`, commonly used with class-based views. * Exceptions raised by the ``render()`` method are now passed to the ``process_exception()`` method of each middleware. * Request middleware can now set :attr:`HttpRequest.urlconf <django.http.HttpRequest.urlconf>` to ``None`` to revert any changes made by previous middleware and return to using the :setting:`ROOT_URLCONF`. Loading
tests/middleware_exceptions/middleware.py 0 → 100644 +8 −0 Original line number Diff line number Diff line from __future__ import unicode_literals from django.http import HttpResponse class ProcessExceptionMiddleware(object): def process_exception(self, request, exception): return HttpResponse('Exception caught')
tests/middleware_exceptions/tests.py +10 −0 Original line number Diff line number Diff line Loading @@ -486,6 +486,16 @@ class MiddlewareTests(BaseMiddlewareExceptionTest): # Check that the right middleware methods have been invoked self.assert_middleware_usage(middleware, True, True, True, True, False) @override_settings( MIDDLEWARE_CLASSES=['middleware_exceptions.middleware.ProcessExceptionMiddleware'], ) def test_exception_in_render_passed_to_process_exception(self): # Repopulate the list of middlewares since it's already been populated # by setUp() before the MIDDLEWARE_CLASSES setting got overridden self.client.handler.load_middleware() response = self.client.get('/middleware_exceptions/exception_in_render/') self.assertEqual(response.content, b'Exception caught') class BadMiddlewareTests(BaseMiddlewareExceptionTest): Loading
tests/middleware_exceptions/urls.py +1 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ urlpatterns = [ url(r'^middleware_exceptions/error/$', views.server_error), url(r'^middleware_exceptions/null_view/$', views.null_view), url(r'^middleware_exceptions/permission_denied/$', views.permission_denied), url(r'^middleware_exceptions/exception_in_render/$', views.exception_in_render), url(r'^middleware_exceptions/template_response/$', views.template_response), url(r'^middleware_exceptions/template_response_error/$', views.template_response_error), Loading