diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index 6a2d0645e0..b34d0e096e 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -112,7 +112,10 @@ class BaseHandler(object): callback, param_dict = resolver.resolve404() return callback(request, **param_dict) except: - return self.handle_uncaught_exception(request, resolver, sys.exc_info()) + try: + return self.handle_uncaught_exception(request, resolver, sys.exc_info()) + finally: + receivers = signals.got_request_exception.send(sender=self.__class__, request=request) except exceptions.PermissionDenied: return http.HttpResponseForbidden('

Permission denied

') except SystemExit: diff --git a/tests/regressiontests/test_client_regress/bad_templates/404.html b/tests/regressiontests/test_client_regress/bad_templates/404.html new file mode 100644 index 0000000000..816bcb9e4e --- /dev/null +++ b/tests/regressiontests/test_client_regress/bad_templates/404.html @@ -0,0 +1,3 @@ +{% block foo %} + +This template is deliberately bad - we want it to raise an exception when it is used. diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py index 14552b7e63..1bffc7d225 100644 --- a/tests/regressiontests/test_client_regress/models.py +++ b/tests/regressiontests/test_client_regress/models.py @@ -1,10 +1,13 @@ """ Regression tests for the Test Client, especially the customized assertions. """ +import os +from django.conf import settings from django.test import Client, TestCase from django.core.urlresolvers import reverse from django.core.exceptions import SuspiciousOperation +from django.template import TemplateDoesNotExist, TemplateSyntaxError class AssertContainsTests(TestCase): def test_contains(self): @@ -306,7 +309,32 @@ class ExceptionTests(TestCase): self.client.get("/test_client_regress/staff_only/") except SuspiciousOperation: self.fail("Staff should be able to visit this page") + +class TemplateExceptionTests(TestCase): + def setUp(self): + self.old_templates = settings.TEMPLATE_DIRS + settings.TEMPLATE_DIRS = () + + def tearDown(self): + settings.TEMPLATE_DIRS = self.old_templates + + def test_no_404_template(self): + "Missing templates are correctly reported by test client" + try: + response = self.client.get("/no_such_view/") + self.fail("Should get error about missing template") + except TemplateDoesNotExist: + pass + def test_bad_404_template(self): + "Errors found when rendering 404 error templates are re-raised" + settings.TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'bad_templates'),) + try: + response = self.client.get("/no_such_view/") + self.fail("Should get error about syntax error in template") + except TemplateSyntaxError: + pass + # We need two different tests to check URLconf substitution - one to check # it was changed, and another one (without self.urls) to check it was reverted on # teardown. This pair of tests relies upon the alphabetical ordering of test execution.