diff --git a/django/views/debug.py b/django/views/debug.py index 624cc3e35f9..34bd57b33df 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -359,6 +359,7 @@ class ExceptionReporter: c['request_FILES_items'] = self.request.FILES.items() c['request_COOKIES_items'] = self.request.COOKIES.items() c['request_insecure_uri'] = self._get_raw_insecure_uri() + c['raising_view_name'] = get_caller(self.request) # Check whether exception info is available if self.exc_type: diff --git a/django/views/templates/technical_500.html b/django/views/templates/technical_500.html index a0f65eb1626..c09f09a19b4 100644 --- a/django/views/templates/technical_500.html +++ b/django/views/templates/technical_500.html @@ -132,6 +132,12 @@ Exception Location: {{ lastframe.filename }}, line {{ lastframe.lineno }}, in {{ lastframe.function }} +{% endif %} +{% if raising_view_name %} + + Raised during: + {{ raising_view_name }} + {% endif %} Python Executable: diff --git a/django/views/templates/technical_500.txt b/django/views/templates/technical_500.txt index 5c86a3139fd..0747de5c85c 100644 --- a/django/views/templates/technical_500.txt +++ b/django/views/templates/technical_500.txt @@ -35,6 +35,7 @@ Traceback (most recent call last): {% endfor %} {% if exception_type %}Exception Type: {{ exception_type }}{% if request %} at {{ request.path_info }}{% endif %} {% if exception_value %}Exception Value: {{ exception_value }}{% endif %}{% endif %}{% endif %} +{% if raising_view_name %}Raised during: {{ raising_view_name }}{% endif %} {% if request %}Request information: {% if user_str %}USER: {{ user_str }}{% endif %} diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 7c49fa51f3b..591013be367 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -199,6 +199,40 @@ class DebugViewTests(SimpleTestCase): html=True, ) + def test_technical_500(self): + with self.assertLogs('django.request', 'ERROR'): + response = self.client.get('/raises500/') + self.assertContains( + response, + 'Raised during:view_tests.views.raises500', + status_code=500, + html=True, + ) + with self.assertLogs('django.request', 'ERROR'): + response = self.client.get('/raises500/', HTTP_ACCEPT='text/plain') + self.assertContains( + response, + 'Raised during: view_tests.views.raises500', + status_code=500, + ) + + def test_classbased_technical_500(self): + with self.assertLogs('django.request', 'ERROR'): + response = self.client.get('/classbased500/') + self.assertContains( + response, + 'Raised during:view_tests.views.Raises500View', + status_code=500, + html=True, + ) + with self.assertLogs('django.request', 'ERROR'): + response = self.client.get('/classbased500/', HTTP_ACCEPT='text/plain') + self.assertContains( + response, + 'Raised during: view_tests.views.Raises500View', + status_code=500, + ) + def test_non_l10ned_numeric_ids(self): """ Numeric IDs and fancy traceback context blocks line numbers shouldn't be localized. diff --git a/tests/view_tests/urls.py b/tests/view_tests/urls.py index f394934f4dd..7a20ff40fa8 100644 --- a/tests/view_tests/urls.py +++ b/tests/view_tests/urls.py @@ -31,6 +31,7 @@ urlpatterns = [ path('technical404/', views.technical404, name='my404'), path('classbased404/', views.Http404View.as_view()), + path('classbased500/', views.Raises500View.as_view()), # i18n views path('i18n/', include('django.conf.urls.i18n')), diff --git a/tests/view_tests/views.py b/tests/view_tests/views.py index ed84286173c..97695ef4938 100644 --- a/tests/view_tests/views.py +++ b/tests/view_tests/views.py @@ -51,6 +51,14 @@ def raises500(request): return technical_500_response(request, *sys.exc_info()) +class Raises500View(View): + def get(self, request): + try: + raise Exception + except Exception: + return technical_500_response(request, *sys.exc_info()) + + def raises400(request): raise SuspiciousOperation