Fixed #33747 -- Added exception notes to the technical 500 debug page.

This commit is contained in:
Giebisch 2022-11-21 16:54:57 +01:00 committed by Mariusz Felisiak
parent 70c945d6b3
commit 80c66e40f7
5 changed files with 42 additions and 5 deletions

View File

@ -396,6 +396,8 @@ class ExceptionReporter:
c["exception_type"] = self.exc_type.__name__ c["exception_type"] = self.exc_type.__name__
if self.exc_value: if self.exc_value:
c["exception_value"] = str(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: if frames:
c["lastframe"] = frames[-1] c["lastframe"] = frames[-1]
return c return c

View File

@ -100,7 +100,7 @@
<div id="summary"> <div id="summary">
<h1>{% if exception_type %}{{ exception_type }}{% else %}Report{% endif %} <h1>{% if exception_type %}{{ exception_type }}{% else %}Report{% endif %}
{% if request %} at {{ request.path_info }}{% endif %}</h1> {% 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"> <table class="meta">
{% if request %} {% if request %}
<tr> <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 %} {% 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 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> </textarea>
<br><br> <br><br>
<input type="submit" value="Share this traceback on a public website"> <input type="submit" value="Share this traceback on a public website">

View File

@ -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 %} {% if frame.context_line %} {% spaceless %}{{ frame.context_line }}{% endspaceless %}{% endif %}{% elif forloop.first %}None{% else %}Traceback: None{% endif %}
{% endfor %} {% endfor %}
{% if exception_type %}Exception Type: {{ exception_type }}{% if request %} at {{ request.path_info }}{% endif %} {% 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 raising_view_name %}Raised during: {{ raising_view_name }}{% endif %}
{% if request %}Request information: {% if request %}Request information:
{% if user_str %}USER: {{ user_str }}{% endif %} {% if user_str %}USER: {{ user_str }}{% endif %}

View File

@ -158,7 +158,7 @@ Email
Error Reporting Error Reporting
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
* ... * The debug page now shows :pep:`exception notes <678>` on Python 3.11+.
File Storage File Storage
~~~~~~~~~~~~ ~~~~~~~~~~~~

View File

@ -7,7 +7,7 @@ import tempfile
import threading import threading
from io import StringIO from io import StringIO
from pathlib import Path from pathlib import Path
from unittest import mock, skipIf from unittest import mock, skipIf, skipUnless
from django.core import mail from django.core import mail
from django.core.files.uploadedfile import SimpleUploadedFile 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.functional import SimpleLazyObject
from django.utils.regex_helper import _lazy_re_compile from django.utils.regex_helper import _lazy_re_compile
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.version import PY311
from django.views.debug import ( from django.views.debug import (
CallableSettingWrapper, CallableSettingWrapper,
ExceptionCycleWarning, ExceptionCycleWarning,
@ -659,6 +660,40 @@ class ExceptionReporterTests(SimpleTestCase):
text, 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): def test_mid_stack_exception_without_traceback(self):
try: try:
try: try: