summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiebisch <rafael@giebisch-mail.de>2022-11-21 16:54:57 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2022-11-25 08:16:10 +0100
commit80c66e40f7beecbd5ee501f757a2e61236597349 (patch)
tree26d3bc257e6f379894a103406a7e80d9dd3f953d
parent70c945d6b31b41b320e57088702077864428fdc0 (diff)
Fixed #33747 -- Added exception notes to the technical 500 debug page.
-rw-r--r--django/views/debug.py2
-rw-r--r--django/views/templates/technical_500.html4
-rw-r--r--django/views/templates/technical_500.txt2
-rw-r--r--docs/releases/4.2.txt2
-rw-r--r--tests/view_tests/tests/test_debug.py37
5 files changed, 42 insertions, 5 deletions
diff --git a/django/views/debug.py b/django/views/debug.py
index 30a1dbc6da..b93afa5737 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -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
diff --git a/django/views/templates/technical_500.html b/django/views/templates/technical_500.html
index 4483145ec3..ae0411729a 100644
--- a/django/views/templates/technical_500.html
+++ b/django/views/templates/technical_500.html
@@ -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">
diff --git a/django/views/templates/technical_500.txt b/django/views/templates/technical_500.txt
index 87cf6b5bbc..a481c5db0d 100644
--- a/django/views/templates/technical_500.txt
+++ b/django/views/templates/technical_500.txt
@@ -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 %}
diff --git a/docs/releases/4.2.txt b/docs/releases/4.2.txt
index 7b3ca37b35..a9841d1af4 100644
--- a/docs/releases/4.2.txt
+++ b/docs/releases/4.2.txt
@@ -158,7 +158,7 @@ Email
Error Reporting
~~~~~~~~~~~~~~~
-* ...
+* The debug page now shows :pep:`exception notes <678>` on Python 3.11+.
File Storage
~~~~~~~~~~~~
diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
index 7224a2b6b6..a9b7625617 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -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'
+ "&lt;script&gt;alert(1);&lt;/script&gt;</pre>",
+ html,
+ )
+ self.assertIn(
+ "Exception Value: Oops\nFirst Note\nSecond Note\n"
+ "&lt;script&gt;alert(1);&lt;/script&gt;",
+ 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: