diff --git a/django/views/debug.py b/django/views/debug.py
index fff67249c6..a32362b31c 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -285,11 +285,23 @@ 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,
+ 'user_str': user_str,
'filtered_POST_items': self.filter.get_post_parameters(self.request).items(),
'settings': get_safe_settings(),
'sys_executable': sys.executable,
@@ -903,9 +915,9 @@ Exception Value: {{ exception_value|force_escape }}
Request information
{% if request %}
- {% if request.user %}
+ {% if user_str %}
USER
- {{ request.user }}
+ {{ user_str }}
{% endif %}
GET
@@ -1104,7 +1116,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 3fe89d9bf3..24fa593621 100644
--- a/tests/view_tests/tests/test_debug.py
+++ b/tests/view_tests/tests/test_debug.py
@@ -515,6 +515,33 @@ class ExceptionReporterTests(SimpleTestCase):
html = reporter.get_traceback_html()
self.assertInHTML('items | 'Oops' | ', 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('ValueError at /test_view/
', html)
+ self.assertIn('Oops
', html)
+ self.assertIn('USER
', html)
+ self.assertIn('[unable to retrieve the current user]
', html)
+
+ text = reporter.get_traceback_text()
+ self.assertIn('USER: [unable to retrieve the current user]', text)
+
class PlainTextReportTests(SimpleTestCase):
rf = RequestFactory()