summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Pelme <andreas@pelme.se>2016-12-03 19:51:32 +0100
committerTim Graham <timograham@gmail.com>2016-12-06 12:58:40 -0500
commitf1f4a7f5a94b449a2174f2598a8e89c421d83917 (patch)
tree8b006a37794f1fd25ce9dc20b284d55b71767d08
parent6265ca25f3fb4f9bf3b38eed8b8eeafdcf02a16e (diff)
downloaddjango-f1f4a7f5a94b449a2174f2598a8e89c421d83917.tar.gz
[1.10.x] Fixed #27567 -- Fixed crash in the debug view when request.user errors.
Backport of 373140b07aa452946ccb6d5b0317fa09ed5bbdc2 from master
-rw-r--r--django/views/debug.py20
-rw-r--r--docs/releases/1.10.5.txt3
-rw-r--r--tests/view_tests/tests/test_debug.py27
3 files changed, 45 insertions, 5 deletions
diff --git a/django/views/debug.py b/django/views/debug.py
index 1bcaaf8169..0ed55fdfe4 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -11,7 +11,7 @@ from django.template.defaultfilters import force_escape, pprint
from django.urls import Resolver404, resolve
from django.utils import lru_cache, six, timezone
from django.utils.datastructures import MultiValueDict
-from django.utils.encoding import force_bytes, smart_text
+from django.utils.encoding import force_bytes, force_text, smart_text
from django.utils.module_loading import import_string
from django.utils.translation import ugettext as _
@@ -285,12 +285,24 @@ class ExceptionReporter(object):
'ascii', errors='replace'
)
from django import get_version
+
+ if self.request is None:
+ user_str = None
+ else:
+ try:
+ user_str = force_text(self.request.user)
+ except Exception:
+ # request.user may raise OperationalError if the database is
+ # unavailable, for example.
+ user_str = '[unable to retrieve the current user]'
+
c = {
'is_email': self.is_email,
'unicode_hint': unicode_hint,
'frames': frames,
'request': self.request,
'filtered_POST': self.filter.get_post_parameters(self.request),
+ 'user_str': user_str,
'settings': get_safe_settings(),
'sys_executable': sys.executable,
'sys_version_info': '%d.%d.%d' % sys.version_info[0:3],
@@ -898,9 +910,9 @@ Exception Value: {{ exception_value|force_escape }}
<h2>Request information</h2>
{% if request %}
- {% if request.user %}
+ {% if user_str %}
<h3 id="user-info">USER</h3>
- <p>{{ request.user }}</p>
+ <p>{{ user_str }}</p>
{% endif %}
<h3 id="get-info">GET</h3>
@@ -1099,7 +1111,7 @@ File "{{ frame.filename }}" in {{ frame.function }}
{% 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 request %}Request information:
-{% if request.user %}USER: {{ request.user }}{% endif %}
+{% if user_str %}USER: {{ user_str }}{% endif %}
GET:{% for k, v in request.GET.items %}
{{ k }} = {{ v|stringformat:"r" }}{% empty %} No GET data{% endfor %}
diff --git a/docs/releases/1.10.5.txt b/docs/releases/1.10.5.txt
index 18827e24a4..ac9270c3c0 100644
--- a/docs/releases/1.10.5.txt
+++ b/docs/releases/1.10.5.txt
@@ -9,4 +9,5 @@ Django 1.10.5 fixes several bugs in 1.10.4.
Bugfixes
========
-* ...
+* Fixed a crash in the debug view if ``request.user`` can't be retrieved, such
+ as if the database is unavailable (:ticket:`27567`).
diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py
index 714723c957..66796c705e 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -464,6 +464,33 @@ class ExceptionReporterTests(SimpleTestCase):
html = reporter.get_traceback_html()
self.assertIn("http://evil.com/", html)
+ def test_exception_fetching_user(self):
+ """
+ The error page can be rendered if the current user can't be retrieved
+ (such as when the database is unavailable).
+ """
+ class ExceptionUser(object):
+ def __str__(self):
+ raise Exception()
+
+ request = self.rf.get('/test_view/')
+ request.user = ExceptionUser()
+
+ try:
+ raise ValueError('Oops')
+ except ValueError:
+ exc_type, exc_value, tb = sys.exc_info()
+
+ reporter = ExceptionReporter(request, exc_type, exc_value, tb)
+ html = reporter.get_traceback_html()
+ self.assertIn('<h1>ValueError at /test_view/</h1>', html)
+ self.assertIn('<pre class="exception_value">Oops</pre>', html)
+ self.assertIn('<h3 id="user-info">USER</h3>', html)
+ self.assertIn('<p>[unable to retrieve the current user]</p>', html)
+
+ text = reporter.get_traceback_text()
+ self.assertIn('USER: [unable to retrieve the current user]', text)
+
class PlainTextReportTests(SimpleTestCase):
rf = RequestFactory()