From 373140b07aa452946ccb6d5b0317fa09ed5bbdc2 Mon Sep 17 00:00:00 2001 From: Andreas Pelme Date: Sat, 3 Dec 2016 19:51:32 +0100 Subject: [PATCH] Fixed #27567 -- Fixed crash in the debug view when request.user errors. --- django/views/debug.py | 18 +++++++++++++++--- docs/releases/1.10.5.txt | 3 ++- tests/view_tests/tests/test_debug.py | 27 +++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) 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()