Fixed #11461: Ensured complete traceback is available on the debug page when an exception is encountered during template rendering, even when running on Python 2.6 or higher. Thanks Glenn.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@12725 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
5a35619b5b
commit
50e46c017e
|
@ -104,20 +104,7 @@ builtins = []
|
||||||
invalid_var_format_string = None
|
invalid_var_format_string = None
|
||||||
|
|
||||||
class TemplateSyntaxError(Exception):
|
class TemplateSyntaxError(Exception):
|
||||||
def __str__(self):
|
pass
|
||||||
try:
|
|
||||||
import cStringIO as StringIO
|
|
||||||
except ImportError:
|
|
||||||
import StringIO
|
|
||||||
output = StringIO.StringIO()
|
|
||||||
output.write(Exception.__str__(self))
|
|
||||||
# Check if we wrapped an exception and print that too.
|
|
||||||
if hasattr(self, 'exc_info'):
|
|
||||||
import traceback
|
|
||||||
output.write('\n\nOriginal ')
|
|
||||||
e = self.exc_info
|
|
||||||
traceback.print_exception(e[0], e[1], e[2], 500, output)
|
|
||||||
return output.getvalue()
|
|
||||||
|
|
||||||
class TemplateDoesNotExist(Exception):
|
class TemplateDoesNotExist(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -76,10 +76,11 @@ class DebugNodeList(NodeList):
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
from sys import exc_info
|
from sys import exc_info
|
||||||
wrapped = TemplateSyntaxError(u'Caught an exception while rendering: %s' % force_unicode(e, errors='replace'))
|
wrapped = TemplateSyntaxError(u'Caught %s while rendering: %s' %
|
||||||
|
(e.__class__.__name__, force_unicode(e, errors='replace')))
|
||||||
wrapped.source = node.source
|
wrapped.source = node.source
|
||||||
wrapped.exc_info = exc_info()
|
wrapped.exc_info = exc_info()
|
||||||
raise wrapped
|
raise wrapped, None, wrapped.exc_info[2]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
class DebugVariableNode(VariableNode):
|
class DebugVariableNode(VariableNode):
|
||||||
|
|
|
@ -216,7 +216,7 @@ class Templates(unittest.TestCase):
|
||||||
except TemplateSyntaxError, e:
|
except TemplateSyntaxError, e:
|
||||||
# Assert that we are getting the template syntax error and not the
|
# Assert that we are getting the template syntax error and not the
|
||||||
# string encoding error.
|
# string encoding error.
|
||||||
self.assertEquals(e.args[0], "Caught an exception while rendering: Reverse for 'will_not_match' with arguments '()' and keyword arguments '{}' not found.")
|
self.assertEquals(e.args[0], "Caught NoReverseMatch while rendering: Reverse for 'will_not_match' with arguments '()' and keyword arguments '{}' not found.")
|
||||||
|
|
||||||
settings.SETTINGS_MODULE = old_settings_module
|
settings.SETTINGS_MODULE = old_settings_module
|
||||||
settings.TEMPLATE_DEBUG = old_template_debug
|
settings.TEMPLATE_DEBUG = old_template_debug
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
from regressiontests.views import BrokenException
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def go_boom(arg):
|
||||||
|
raise BrokenException(arg)
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
|
import inspect
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
|
from django.template import TemplateSyntaxError
|
||||||
|
|
||||||
from regressiontests.views import BrokenException, except_args
|
from regressiontests.views import BrokenException, except_args
|
||||||
|
|
||||||
|
@ -9,9 +12,12 @@ class DebugViewTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.old_debug = settings.DEBUG
|
self.old_debug = settings.DEBUG
|
||||||
settings.DEBUG = True
|
settings.DEBUG = True
|
||||||
|
self.old_template_debug = settings.TEMPLATE_DEBUG
|
||||||
|
settings.TEMPLATE_DEBUG = True
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
settings.DEBUG = self.old_debug
|
settings.DEBUG = self.old_debug
|
||||||
|
settings.TEMPLATE_DEBUG = self.old_template_debug
|
||||||
|
|
||||||
def test_files(self):
|
def test_files(self):
|
||||||
response = self.client.get('/views/raises/')
|
response = self.client.get('/views/raises/')
|
||||||
|
@ -33,3 +39,13 @@ class DebugViewTests(TestCase):
|
||||||
self.assertRaises(BrokenException, self.client.get,
|
self.assertRaises(BrokenException, self.client.get,
|
||||||
reverse('view_exception', args=(n,)))
|
reverse('view_exception', args=(n,)))
|
||||||
|
|
||||||
|
def test_template_exceptions(self):
|
||||||
|
for n in range(len(except_args)):
|
||||||
|
try:
|
||||||
|
self.client.get(reverse('template_exception', args=(n,)))
|
||||||
|
except TemplateSyntaxError, e:
|
||||||
|
raising_loc = inspect.trace()[-1][-2][0].strip()
|
||||||
|
self.failIf(raising_loc.find('raise BrokenException') == -1,
|
||||||
|
"Failed to find 'raise BrokenException' in last frame of traceback, instead found: %s" %
|
||||||
|
raising_loc)
|
||||||
|
|
||||||
|
|
|
@ -109,4 +109,5 @@ urlpatterns += patterns('django.views.generic.simple',
|
||||||
|
|
||||||
urlpatterns += patterns('regressiontests.views.views',
|
urlpatterns += patterns('regressiontests.views.views',
|
||||||
url(r'view_exception/(?P<n>\d+)/$', 'view_exception', name='view_exception'),
|
url(r'view_exception/(?P<n>\d+)/$', 'view_exception', name='view_exception'),
|
||||||
|
url(r'template_exception/(?P<n>\d+)/$', 'template_exception', name='template_exception'),
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django import forms
|
||||||
from django.views.debug import technical_500_response
|
from django.views.debug import technical_500_response
|
||||||
from django.views.generic.create_update import create_object
|
from django.views.generic.create_update import create_object
|
||||||
from django.core.urlresolvers import get_resolver
|
from django.core.urlresolvers import get_resolver
|
||||||
|
from django.shortcuts import render_to_response
|
||||||
|
|
||||||
from regressiontests.views import BrokenException, except_args
|
from regressiontests.views import BrokenException, except_args
|
||||||
|
|
||||||
|
@ -52,3 +53,7 @@ def redirect(request):
|
||||||
def view_exception(request, n):
|
def view_exception(request, n):
|
||||||
raise BrokenException(except_args[int(n)])
|
raise BrokenException(except_args[int(n)])
|
||||||
|
|
||||||
|
def template_exception(request, n):
|
||||||
|
return render_to_response('debug/template_exception.html',
|
||||||
|
{'arg': except_args[int(n)]})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue