From 38eacbde62cd83ffaa64db7719c2c643f69551e0 Mon Sep 17 00:00:00 2001 From: Luca Ferroni Date: Sun, 19 Apr 2015 15:30:01 +0200 Subject: [PATCH] Refs #23643 -- Fixed debug view regression on Python 2. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks Tomáš Ehrlich for help with the patch. --- django/views/debug.py | 6 ++++-- tests/view_tests/tests/test_debug.py | 25 ++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/django/views/debug.py b/django/views/debug.py index ae1352106a..78ce764cf0 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -409,7 +409,7 @@ class ExceptionReporter(object): # sometimes in Python 3), take the traceback from self.tb (Python 2 # doesn't have a __traceback__ attribute on Exception) exc_value = exceptions.pop() - tb = self.tb if not exceptions else exc_value.__traceback__ + tb = self.tb if six.PY2 or not exceptions else exc_value.__traceback__ while tb is not None: # Support for __traceback_hide__ which is used by a few libraries @@ -444,7 +444,9 @@ class ExceptionReporter(object): # If the traceback for current exception is consumed, try the # other exception. - if not tb.tb_next and exceptions: + if six.PY2: + tb = tb.tb_next + elif not tb.tb_next and exceptions: exc_value = exceptions.pop() tb = exc_value.__traceback__ else: diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index ac8cbcdb11..4f3a9d6161 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -14,13 +14,16 @@ from unittest import skipIf from django.core import mail from django.core.files.uploadedfile import SimpleUploadedFile from django.core.urlresolvers import reverse +from django.db import DatabaseError, connection from django.template import TemplateDoesNotExist from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.utils import LoggingCaptureMixin from django.utils import six from django.utils.encoding import force_bytes, force_text from django.utils.functional import SimpleLazyObject -from django.views.debug import CallableSettingWrapper, ExceptionReporter +from django.views.debug import ( + CallableSettingWrapper, ExceptionReporter, technical_500_response, +) from .. import BrokenException, except_args from ..views import ( @@ -194,6 +197,26 @@ class DebugViewTests(LoggingCaptureMixin, SimpleTestCase): ) +class DebugViewQueriesAllowedTests(SimpleTestCase): + # May need a query to initialize MySQL connection + allow_database_queries = True + + def test_handle_db_exception(self): + """ + Ensure the debug view works when a database exception is raised by + performing an invalid query and passing the exception to the debug view. + """ + with connection.cursor() as cursor: + try: + cursor.execute('INVALID SQL') + except DatabaseError: + exc_info = sys.exc_info() + + rf = RequestFactory() + response = technical_500_response(rf.get('/'), *exc_info) + self.assertContains(response, 'OperationalError at /', status_code=500) + + @override_settings( DEBUG=True, ROOT_URLCONF="view_tests.urls",