Fixed #27567 -- Fixed crash in the debug view when request.user errors.

This commit is contained in:
Andreas Pelme 2016-12-03 19:51:32 +01:00 committed by Tim Graham
parent 8f76673f34
commit 373140b07a
3 changed files with 44 additions and 4 deletions

View File

@ -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 }}
<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>
@ -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 %}

View File

@ -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`).

View File

@ -515,6 +515,33 @@ class ExceptionReporterTests(SimpleTestCase):
html = reporter.get_traceback_html()
self.assertInHTML('<td>items</td><td class="code"><pre>&#39;Oops&#39;</pre></td>', 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()