mirror of https://github.com/django/django.git
Fixed #33747 -- Added exception notes to the technical 500 debug page.
This commit is contained in:
parent
70c945d6b3
commit
80c66e40f7
|
@ -396,6 +396,8 @@ class ExceptionReporter:
|
|||
c["exception_type"] = self.exc_type.__name__
|
||||
if self.exc_value:
|
||||
c["exception_value"] = str(self.exc_value)
|
||||
if exc_notes := getattr(self.exc_value, "__notes__", None):
|
||||
c["exception_notes"] = "\n" + "\n".join(exc_notes)
|
||||
if frames:
|
||||
c["lastframe"] = frames[-1]
|
||||
return c
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
<div id="summary">
|
||||
<h1>{% if exception_type %}{{ exception_type }}{% else %}Report{% endif %}
|
||||
{% if request %} at {{ request.path_info }}{% endif %}</h1>
|
||||
<pre class="exception_value">{% if exception_value %}{{ exception_value|force_escape }}{% else %}No exception message supplied{% endif %}</pre>
|
||||
<pre class="exception_value">{% if exception_value %}{{ exception_value|force_escape }}{% if exception_notes %}{{ exception_notes }}{% endif %}{% else %}No exception message supplied{% endif %}</pre>
|
||||
<table class="meta">
|
||||
{% if request %}
|
||||
<tr>
|
||||
|
@ -330,7 +330,7 @@ During handling of the above exception ({{ frame.exc_cause|force_escape }}), ano
|
|||
{% if frame.context_line %} {% spaceless %}{{ frame.context_line }}{% endspaceless %}{% endif %}{% elif forloop.first %}None{% else %}Traceback: None{% endif %}{% endfor %}
|
||||
|
||||
Exception Type: {{ exception_type }}{% if request %} at {{ request.path_info }}{% endif %}
|
||||
Exception Value: {{ exception_value|force_escape }}
|
||||
Exception Value: {{ exception_value|force_escape }}{% if exception_notes %}{{ exception_notes }}{% endif %}
|
||||
</textarea>
|
||||
<br><br>
|
||||
<input type="submit" value="Share this traceback on a public website">
|
||||
|
|
|
@ -34,7 +34,7 @@ Traceback (most recent call last):
|
|||
{% if frame.context_line %} {% spaceless %}{{ frame.context_line }}{% endspaceless %}{% endif %}{% elif forloop.first %}None{% else %}Traceback: None{% endif %}
|
||||
{% 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 exception_value %}Exception Value: {{ exception_value }}{% endif %}{% if exception_notes %}{{ exception_notes }}{% endif %}{% endif %}{% endif %}
|
||||
{% if raising_view_name %}Raised during: {{ raising_view_name }}{% endif %}
|
||||
{% if request %}Request information:
|
||||
{% if user_str %}USER: {{ user_str }}{% endif %}
|
||||
|
|
|
@ -158,7 +158,7 @@ Email
|
|||
Error Reporting
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
* ...
|
||||
* The debug page now shows :pep:`exception notes <678>` on Python 3.11+.
|
||||
|
||||
File Storage
|
||||
~~~~~~~~~~~~
|
||||
|
|
|
@ -7,7 +7,7 @@ import tempfile
|
|||
import threading
|
||||
from io import StringIO
|
||||
from pathlib import Path
|
||||
from unittest import mock, skipIf
|
||||
from unittest import mock, skipIf, skipUnless
|
||||
|
||||
from django.core import mail
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
|
@ -22,6 +22,7 @@ from django.urls.converters import IntConverter
|
|||
from django.utils.functional import SimpleLazyObject
|
||||
from django.utils.regex_helper import _lazy_re_compile
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.version import PY311
|
||||
from django.views.debug import (
|
||||
CallableSettingWrapper,
|
||||
ExceptionCycleWarning,
|
||||
|
@ -659,6 +660,40 @@ class ExceptionReporterTests(SimpleTestCase):
|
|||
text,
|
||||
)
|
||||
|
||||
@skipUnless(PY311, "Exception notes were added in Python 3.11.")
|
||||
def test_exception_with_notes(self):
|
||||
request = self.rf.get("/test_view/")
|
||||
try:
|
||||
try:
|
||||
raise RuntimeError("Oops")
|
||||
except Exception as err:
|
||||
err.add_note("First Note")
|
||||
err.add_note("Second Note")
|
||||
err.add_note(mark_safe("<script>alert(1);</script>"))
|
||||
raise err
|
||||
except Exception:
|
||||
exc_type, exc_value, tb = sys.exc_info()
|
||||
|
||||
reporter = ExceptionReporter(request, exc_type, exc_value, tb)
|
||||
html = reporter.get_traceback_html()
|
||||
self.assertIn(
|
||||
'<pre class="exception_value">Oops\nFirst Note\nSecond Note\n'
|
||||
"<script>alert(1);</script></pre>",
|
||||
html,
|
||||
)
|
||||
self.assertIn(
|
||||
"Exception Value: Oops\nFirst Note\nSecond Note\n"
|
||||
"<script>alert(1);</script>",
|
||||
html,
|
||||
)
|
||||
|
||||
text = reporter.get_traceback_text()
|
||||
self.assertIn(
|
||||
"Exception Value: Oops\nFirst Note\nSecond Note\n"
|
||||
"<script>alert(1);</script>",
|
||||
text,
|
||||
)
|
||||
|
||||
def test_mid_stack_exception_without_traceback(self):
|
||||
try:
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue