diff options
author | Andreas Pelme <andreas@pelme.se> | 2016-12-03 19:51:32 +0100 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2016-12-06 12:58:40 -0500 |
commit | f1f4a7f5a94b449a2174f2598a8e89c421d83917 (patch) | |
tree | 8b006a37794f1fd25ce9dc20b284d55b71767d08 | |
parent | 6265ca25f3fb4f9bf3b38eed8b8eeafdcf02a16e (diff) | |
download | django-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.py | 20 | ||||
-rw-r--r-- | docs/releases/1.10.5.txt | 3 | ||||
-rw-r--r-- | tests/view_tests/tests/test_debug.py | 27 |
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() |