mirror of https://github.com/django/django.git
Fixed #32105 -- Added template paths as ExceptionReporter class attributes.
This allows replacement of the debugging templates without having to copy-paste the `get_traceback_html` and `get_traceback_text` functions into a subclass. Thanks to Nick Pope for review.
This commit is contained in:
parent
411cc0ae18
commit
68e33b347d
|
@ -245,6 +245,9 @@ class SafeExceptionReporterFilter:
|
||||||
|
|
||||||
class ExceptionReporter:
|
class ExceptionReporter:
|
||||||
"""Organize and coordinate reporting on exceptions."""
|
"""Organize and coordinate reporting on exceptions."""
|
||||||
|
html_template_path = CURRENT_DIR / 'templates' / 'technical_500.html'
|
||||||
|
text_template_path = CURRENT_DIR / 'templates' / 'technical_500.txt'
|
||||||
|
|
||||||
def __init__(self, request, exc_type, exc_value, tb, is_email=False):
|
def __init__(self, request, exc_type, exc_value, tb, is_email=False):
|
||||||
self.request = request
|
self.request = request
|
||||||
self.filter = get_exception_reporter_filter(self.request)
|
self.filter = get_exception_reporter_filter(self.request)
|
||||||
|
@ -331,14 +334,14 @@ class ExceptionReporter:
|
||||||
|
|
||||||
def get_traceback_html(self):
|
def get_traceback_html(self):
|
||||||
"""Return HTML version of debug 500 HTTP error page."""
|
"""Return HTML version of debug 500 HTTP error page."""
|
||||||
with Path(CURRENT_DIR, 'templates', 'technical_500.html').open(encoding='utf-8') as fh:
|
with self.html_template_path.open(encoding='utf-8') as fh:
|
||||||
t = DEBUG_ENGINE.from_string(fh.read())
|
t = DEBUG_ENGINE.from_string(fh.read())
|
||||||
c = Context(self.get_traceback_data(), use_l10n=False)
|
c = Context(self.get_traceback_data(), use_l10n=False)
|
||||||
return t.render(c)
|
return t.render(c)
|
||||||
|
|
||||||
def get_traceback_text(self):
|
def get_traceback_text(self):
|
||||||
"""Return plain text version of debug 500 HTTP error page."""
|
"""Return plain text version of debug 500 HTTP error page."""
|
||||||
with Path(CURRENT_DIR, 'templates', 'technical_500.txt').open(encoding='utf-8') as fh:
|
with self.text_template_path.open(encoding='utf-8') as fh:
|
||||||
t = DEBUG_ENGINE.from_string(fh.read())
|
t = DEBUG_ENGINE.from_string(fh.read())
|
||||||
c = Context(self.get_traceback_data(), autoescape=False, use_l10n=False)
|
c = Context(self.get_traceback_data(), autoescape=False, use_l10n=False)
|
||||||
return t.render(c)
|
return t.render(c)
|
||||||
|
|
|
@ -325,6 +325,22 @@ Your custom reporter class needs to inherit from
|
||||||
|
|
||||||
.. class:: ExceptionReporter
|
.. class:: ExceptionReporter
|
||||||
|
|
||||||
|
.. attribute:: html_template_path
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
A :class:`pathlib.Path` representing the absolute filesystem path to a
|
||||||
|
template for rendering the HTML representation of the exception.
|
||||||
|
Defaults to the Django provided template.
|
||||||
|
|
||||||
|
.. attribute:: text_template_path
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
|
||||||
|
A :class:`pathlib.Path` representing the absolute filesystem path to a
|
||||||
|
template for rendering the plain-text representation of the exception.
|
||||||
|
Defaults to the Django provided template.
|
||||||
|
|
||||||
.. method:: get_traceback_data()
|
.. method:: get_traceback_data()
|
||||||
|
|
||||||
Return a dictionary containing traceback information.
|
Return a dictionary containing traceback information.
|
||||||
|
|
|
@ -188,7 +188,10 @@ Email
|
||||||
Error Reporting
|
Error Reporting
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
* ...
|
* Custom :class:`~django.views.debug.ExceptionReporter` subclasses can now set
|
||||||
|
the :attr:`~django.views.debug.ExceptionReporter.html_template_path` and
|
||||||
|
:attr:`~django.views.debug.ExceptionReporter.text_template_path` class
|
||||||
|
attributes to override the templates used to render exception reports.
|
||||||
|
|
||||||
File Storage
|
File Storage
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
<h1>Oh no, an error occurred!</h1>
|
|
@ -0,0 +1 @@
|
||||||
|
Oh dear, an error occurred!
|
|
@ -293,6 +293,21 @@ class DebugViewTests(SimpleTestCase):
|
||||||
response = self.client.get('/raises500/')
|
response = self.client.get('/raises500/')
|
||||||
self.assertContains(response, 'custom traceback text', status_code=500)
|
self.assertContains(response, 'custom traceback text', status_code=500)
|
||||||
|
|
||||||
|
@override_settings(DEFAULT_EXCEPTION_REPORTER='view_tests.views.TemplateOverrideExceptionReporter')
|
||||||
|
def test_template_override_exception_reporter(self):
|
||||||
|
with self.assertLogs('django.request', 'ERROR'):
|
||||||
|
response = self.client.get('/raises500/')
|
||||||
|
self.assertContains(
|
||||||
|
response,
|
||||||
|
'<h1>Oh no, an error occurred!</h1>',
|
||||||
|
status_code=500,
|
||||||
|
html=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertLogs('django.request', 'ERROR'):
|
||||||
|
response = self.client.get('/raises500/', HTTP_ACCEPT='text/plain')
|
||||||
|
self.assertContains(response, 'Oh dear, an error occurred!', status_code=500)
|
||||||
|
|
||||||
|
|
||||||
class DebugViewQueriesAllowedTests(SimpleTestCase):
|
class DebugViewQueriesAllowedTests(SimpleTestCase):
|
||||||
# May need a query to initialize MySQL connection
|
# May need a query to initialize MySQL connection
|
||||||
|
|
|
@ -2,6 +2,7 @@ import datetime
|
||||||
import decimal
|
import decimal
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from django.core.exceptions import (
|
from django.core.exceptions import (
|
||||||
BadRequest, PermissionDenied, SuspiciousOperation,
|
BadRequest, PermissionDenied, SuspiciousOperation,
|
||||||
|
@ -18,6 +19,8 @@ from django.views.decorators.debug import (
|
||||||
sensitive_post_parameters, sensitive_variables,
|
sensitive_post_parameters, sensitive_variables,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TEMPLATES_PATH = Path(__file__).resolve().parent / 'templates'
|
||||||
|
|
||||||
|
|
||||||
def index_page(request):
|
def index_page(request):
|
||||||
"""Dummy index page"""
|
"""Dummy index page"""
|
||||||
|
@ -240,6 +243,11 @@ class CustomExceptionReporter(ExceptionReporter):
|
||||||
return self.custom_traceback_text
|
return self.custom_traceback_text
|
||||||
|
|
||||||
|
|
||||||
|
class TemplateOverrideExceptionReporter(ExceptionReporter):
|
||||||
|
html_template_path = TEMPLATES_PATH / 'my_technical_500.html'
|
||||||
|
text_template_path = TEMPLATES_PATH / 'my_technical_500.txt'
|
||||||
|
|
||||||
|
|
||||||
def custom_reporter_class_view(request):
|
def custom_reporter_class_view(request):
|
||||||
request.exception_reporter_class = CustomExceptionReporter
|
request.exception_reporter_class = CustomExceptionReporter
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue