Skip to content

Commit

Permalink
Fixed #16770 -- Eliminated TemplateSyntaxError wrapping of exceptions…
Browse files Browse the repository at this point in the history
…. Thanks to Justin Myles-Holmes for report and draft patch.

Exceptions raised in templates were previously wrapped in TemplateSyntaxError
(in TEMPLATE_DEBUG mode only) in order to provide template source details on
the debug 500 page. The same debug information is now provided by annotating
exceptions rather than wrapping them. This makes catching exceptions raised
from templates more sane, as it's consistent in or out of DEBUG, and you can
catch the specific exception(s) you care about rather than having to also catch
TemplateSyntaxError and unwrap it.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16833 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
carljm committed Sep 16, 2011
1 parent 608548b commit 4397c58
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 78 deletions.
34 changes: 14 additions & 20 deletions django/template/debug.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from django.utils.safestring import SafeData, EscapeData from django.utils.safestring import SafeData, EscapeData
from django.utils.formats import localize from django.utils.formats import localize



class DebugLexer(Lexer): class DebugLexer(Lexer):
def __init__(self, template_string, origin): def __init__(self, template_string, origin):
super(DebugLexer, self).__init__(template_string, origin) super(DebugLexer, self).__init__(template_string, origin)
Expand Down Expand Up @@ -42,9 +43,9 @@ def exit_command(self):
def error(self, token, msg): def error(self, token, msg):
return self.source_error(token.source, msg) return self.source_error(token.source, msg)


def source_error(self, source,msg): def source_error(self, source, msg):
e = TemplateSyntaxError(msg) e = TemplateSyntaxError(msg)
e.source = source e.django_template_source = source
return e return e


def create_nodelist(self): def create_nodelist(self):
Expand All @@ -63,38 +64,31 @@ def unclosed_block_tag(self, parse_until):
raise self.source_error(source, msg) raise self.source_error(source, msg)


def compile_function_error(self, token, e): def compile_function_error(self, token, e):
if not hasattr(e, 'source'): if not hasattr(e, 'django_template_source'):
e.source = token.source e.django_template_source = token.source


class DebugNodeList(NodeList): class DebugNodeList(NodeList):
def render_node(self, node, context): def render_node(self, node, context):
try: try:
result = node.render(context) return node.render(context)
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = node.source
raise
except Exception, e: except Exception, e:
from sys import exc_info if not hasattr(e, 'django_template_source'):
wrapped = TemplateSyntaxError(u'Caught %s while rendering: %s' % e.django_template_source = node.source
(e.__class__.__name__, force_unicode(e, errors='replace'))) raise
wrapped.source = getattr(e, 'template_node_source', node.source)
wrapped.exc_info = exc_info()
raise wrapped, None, wrapped.exc_info[2]
return result


class DebugVariableNode(VariableNode): class DebugVariableNode(VariableNode):
def render(self, context): def render(self, context):
try: try:
output = self.filter_expression.resolve(context) output = self.filter_expression.resolve(context)
output = localize(output, use_l10n=context.use_l10n) output = localize(output, use_l10n=context.use_l10n)
output = force_unicode(output) output = force_unicode(output)
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = self.source
raise
except UnicodeDecodeError: except UnicodeDecodeError:
return '' return ''
except Exception, e:
if not hasattr(e, 'django_template_source'):
e.django_template_source = self.source
raise
if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData): if (context.autoescape and not isinstance(output, SafeData)) or isinstance(output, EscapeData):
return escape(output) return escape(output)
else: else:
Expand Down
10 changes: 4 additions & 6 deletions django/template/defaulttags.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -227,17 +227,15 @@ def render(self, context):
context.update(unpacked_vars) context.update(unpacked_vars)
else: else:
context[self.loopvars[0]] = item context[self.loopvars[0]] = item
# In TEMPLATE_DEBUG mode providing source of the node which # In TEMPLATE_DEBUG mode provide source of the node which
# actually raised an exception to DefaultNodeList.render_node # actually raised the exception
if settings.TEMPLATE_DEBUG: if settings.TEMPLATE_DEBUG:
for node in self.nodelist_loop: for node in self.nodelist_loop:
try: try:
nodelist.append(node.render(context)) nodelist.append(node.render(context))
except Exception, e: except Exception, e:
if not hasattr(e, 'template_node_source'): if not hasattr(e, 'django_template_source'):
from sys import exc_info e.django_template_source = node.source
e.template_node_source = node.source
raise e, None, exc_info()[2]
raise raise
else: else:
for node in self.nodelist_loop: for node in self.nodelist_loop:
Expand Down
11 changes: 5 additions & 6 deletions django/views/debug.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.http import (HttpResponse, HttpResponseServerError, from django.http import (HttpResponse, HttpResponseServerError,
HttpResponseNotFound, HttpRequest, build_request_repr) HttpResponseNotFound, HttpRequest, build_request_repr)
from django.template import (Template, Context, TemplateDoesNotExist, from django.template import Template, Context, TemplateDoesNotExist
TemplateSyntaxError)
from django.template.defaultfilters import force_escape, pprint from django.template.defaultfilters import force_escape, pprint
from django.utils.html import escape from django.utils.html import escape
from django.utils.importlib import import_module from django.utils.importlib import import_module
Expand Down Expand Up @@ -223,8 +222,8 @@ def get_traceback_html(self):
'loader': loader_name, 'loader': loader_name,
'templates': template_list, 'templates': template_list,
}) })
if (settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source') and if (settings.TEMPLATE_DEBUG and
isinstance(self.exc_value, TemplateSyntaxError)): hasattr(self.exc_value, 'django_template_source')):
self.get_template_exception_info() self.get_template_exception_info()


frames = self.get_traceback_frames() frames = self.get_traceback_frames()
Expand Down Expand Up @@ -268,7 +267,7 @@ def get_traceback_html(self):
return t.render(c) return t.render(c)


def get_template_exception_info(self): def get_template_exception_info(self):
origin, (start, end) = self.exc_value.source origin, (start, end) = self.exc_value.django_template_source
template_source = origin.reload() template_source = origin.reload()
context_lines = 10 context_lines = 10
line = 0 line = 0
Expand Down Expand Up @@ -626,7 +625,7 @@ def empty_urlconf(request):
{% endif %} {% endif %}
{% if template_info %} {% if template_info %}
<div id="template"> <div id="template">
<h2>Template error</h2> <h2>Error during template rendering</h2>
<p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p> <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
<h3>{{ template_info.message }}</h3> <h3>{{ template_info.message }}</h3>
<table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}"> <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}">
Expand Down
16 changes: 5 additions & 11 deletions tests/regressiontests/templates/nodelist.py
Original file line number Original file line Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.conf import settings from django.template import VariableNode, Context
from django.template import VariableNode, Context, TemplateSyntaxError
from django.template.loader import get_template_from_string from django.template.loader import get_template_from_string
from django.utils.unittest import TestCase from django.utils.unittest import TestCase
from django.test.utils import override_settings


class NodelistTest(TestCase): class NodelistTest(TestCase):


Expand Down Expand Up @@ -35,13 +35,7 @@ class ErrorIndexTest(TestCase):
Checks whether index of error is calculated correctly in Checks whether index of error is calculated correctly in
template debugger in for loops. Refs ticket #5831 template debugger in for loops. Refs ticket #5831
""" """
def setUp(self): @override_settings(DEBUG=True, TEMPLATE_DEBUG = True)
self.old_template_debug = settings.TEMPLATE_DEBUG
settings.TEMPLATE_DEBUG = True

def tearDown(self):
settings.TEMPLATE_DEBUG = self.old_template_debug

def test_correct_exception_index(self): def test_correct_exception_index(self):
tests = [ tests = [
('{% load bad_tag %}{% for i in range %}{% badsimpletag %}{% endfor %}', (38, 56)), ('{% load bad_tag %}{% for i in range %}{% badsimpletag %}{% endfor %}', (38, 56)),
Expand All @@ -58,7 +52,7 @@ def test_correct_exception_index(self):
template = get_template_from_string(source) template = get_template_from_string(source)
try: try:
template.render(context) template.render(context)
except TemplateSyntaxError, e: except (RuntimeError, TypeError), e:
error_source_index = e.source[1] error_source_index = e.django_template_source[1]
self.assertEqual(error_source_index, self.assertEqual(error_source_index,
expected_error_source_index) expected_error_source_index)
74 changes: 40 additions & 34 deletions tests/regressiontests/templates/tests.py
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from __future__ import with_statement

from django.conf import settings from django.conf import settings


if __name__ == '__main__': if __name__ == '__main__':
Expand All @@ -20,7 +22,7 @@
from django.template import loader from django.template import loader
from django.template.loaders import app_directories, filesystem, cached from django.template.loaders import app_directories, filesystem, cached
from django.test.utils import (get_warnings_state, restore_warnings_state, from django.test.utils import (get_warnings_state, restore_warnings_state,
setup_test_template_loader, restore_template_loaders) setup_test_template_loader, restore_template_loaders, override_settings)
from django.utils import unittest from django.utils import unittest
from django.utils.formats import date_format from django.utils.formats import date_format
from django.utils.translation import activate, deactivate, ugettext as _ from django.utils.translation import activate, deactivate, ugettext as _
Expand Down Expand Up @@ -309,9 +311,9 @@ def test_extends_include_missing_baseloader(self):
r = None r = None
try: try:
r = tmpl.render(template.Context({})) r = tmpl.render(template.Context({}))
except template.TemplateSyntaxError, e: except template.TemplateDoesNotExist, e:
settings.TEMPLATE_DEBUG = old_td settings.TEMPLATE_DEBUG = old_td
self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html') self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r) self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
finally: finally:
loader.template_source_loaders = old_loaders loader.template_source_loaders = old_loaders
Expand All @@ -336,17 +338,17 @@ def test_extends_include_missing_cachedloader(self):
r = None r = None
try: try:
r = tmpl.render(template.Context({})) r = tmpl.render(template.Context({}))
except template.TemplateSyntaxError, e: except template.TemplateDoesNotExist, e:
self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html') self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r) self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)


# For the cached loader, repeat the test, to ensure the first attempt did not cache a # For the cached loader, repeat the test, to ensure the first attempt did not cache a
# result that behaves incorrectly on subsequent attempts. # result that behaves incorrectly on subsequent attempts.
tmpl = loader.get_template(load_name) tmpl = loader.get_template(load_name)
try: try:
tmpl.render(template.Context({})) tmpl.render(template.Context({}))
except template.TemplateSyntaxError, e: except template.TemplateDoesNotExist, e:
self.assertEqual(e.args[0], 'Caught TemplateDoesNotExist while rendering: missing.html') self.assertEqual(e.args[0], 'missing.html')
self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r) self.assertEqual(r, None, 'Template rendering unexpectedly succeeded, produced: ->%r<-' % r)
finally: finally:
loader.template_source_loaders = old_loaders loader.template_source_loaders = old_loaders
Expand All @@ -358,27 +360,31 @@ def test_token_smart_split(self):
split = token.split_contents() split = token.split_contents()
self.assertEqual(split, ["sometag", '_("Page not found")', 'value|yesno:_("yes,no")']) self.assertEqual(split, ["sometag", '_("Page not found")', 'value|yesno:_("yes,no")'])


@override_settings(SETTINGS_MODULE=None, TEMPLATE_DEBUG=True)
def test_url_reverse_no_settings_module(self): def test_url_reverse_no_settings_module(self):
# Regression test for #9005 # Regression test for #9005
from django.template import Template, Context, TemplateSyntaxError from django.template import Template, Context

old_settings_module = settings.SETTINGS_MODULE
old_template_debug = settings.TEMPLATE_DEBUG

settings.SETTINGS_MODULE = None
settings.TEMPLATE_DEBUG = True


t = Template('{% url will_not_match %}') t = Template('{% url will_not_match %}')
c = Context() c = Context()
try: with self.assertRaises(urlresolvers.NoReverseMatch):
rendered = t.render(c) t.render(c)
except TemplateSyntaxError, e:
# Assert that we are getting the template syntax error and not the
# string encoding error. @override_settings(DEBUG=True, TEMPLATE_DEBUG = True)
self.assertEqual(e.args[0], "Caught NoReverseMatch while rendering: Reverse for 'will_not_match' with arguments '()' and keyword arguments '{}' not found.") def test_no_wrapped_exception(self):
"""
The template system doesn't wrap exceptions, but annotates them.
Refs #16770
"""
c = Context({"coconuts": lambda: 42 / 0})
t = Template("{{ coconuts }}")
with self.assertRaises(ZeroDivisionError) as cm:
t.render(c)

self.assertEqual(cm.exception.django_template_source[1], (0, 14))


settings.SETTINGS_MODULE = old_settings_module
settings.TEMPLATE_DEBUG = old_template_debug


def test_invalid_block_suggestion(self): def test_invalid_block_suggestion(self):
# See #7876 # See #7876
Expand Down Expand Up @@ -666,7 +672,7 @@ def get_template_tests(self):


# In methods that raise an exception without a # In methods that raise an exception without a
# "silent_variable_attribute" set to True, the exception propagates # "silent_variable_attribute" set to True, the exception propagates
'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)), 'filter-syntax14': (r'1{{ var.method4 }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException)),


# Escaped backslash in argument # Escaped backslash in argument
'filter-syntax15': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'), 'filter-syntax15': (r'{{ var|default_if_none:"foo\bar" }}', {"var": None}, r'foo\bar'),
Expand Down Expand Up @@ -695,8 +701,8 @@ def get_template_tests(self):
# In attribute and dict lookups that raise an unexpected exception # In attribute and dict lookups that raise an unexpected exception
# without a "silent_variable_attribute" set to True, the exception # without a "silent_variable_attribute" set to True, the exception
# propagates # propagates
'filter-syntax23': (r'1{{ var.noisy_fail_key }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)), 'filter-syntax23': (r'1{{ var.noisy_fail_key }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException)),
'filter-syntax24': (r'1{{ var.noisy_fail_attribute }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException, template.TemplateSyntaxError)), 'filter-syntax24': (r'1{{ var.noisy_fail_attribute }}2', {"var": SomeClass()}, (SomeOtherException, SomeOtherException)),


### COMMENT SYNTAX ######################################################## ### COMMENT SYNTAX ########################################################
'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"), 'comment-syntax01': ("{# this is hidden #}hello", {}, "hello"),
Expand Down Expand Up @@ -753,7 +759,7 @@ def get_template_tests(self):
### EXCEPTIONS ############################################################ ### EXCEPTIONS ############################################################


# Raise exception for invalid template name # Raise exception for invalid template name
'exception01': ("{% extends 'nonexistent' %}", {}, (template.TemplateDoesNotExist, template.TemplateDoesNotExist, template.TemplateSyntaxError)), 'exception01': ("{% extends 'nonexistent' %}", {}, (template.TemplateDoesNotExist, template.TemplateDoesNotExist)),


# Raise exception for invalid template name (in variable) # Raise exception for invalid template name (in variable)
'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)), 'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)),
Expand Down Expand Up @@ -1050,7 +1056,7 @@ def get_template_tests(self):
'include-fail2': ('{% load broken_tag %}', {}, template.TemplateSyntaxError), 'include-fail2': ('{% load broken_tag %}', {}, template.TemplateSyntaxError),
'include-error07': ('{% include "include-fail1" %}', {}, ('', '', RuntimeError)), 'include-error07': ('{% include "include-fail1" %}', {}, ('', '', RuntimeError)),
'include-error08': ('{% include "include-fail2" %}', {}, ('', '', template.TemplateSyntaxError)), 'include-error08': ('{% include "include-fail2" %}', {}, ('', '', template.TemplateSyntaxError)),
'include-error09': ('{% include failed_include %}', {'failed_include': 'include-fail1'}, ('', '', template.TemplateSyntaxError)), 'include-error09': ('{% include failed_include %}', {'failed_include': 'include-fail1'}, ('', '', RuntimeError)),
'include-error10': ('{% include failed_include %}', {'failed_include': 'include-fail2'}, ('', '', template.TemplateSyntaxError)), 'include-error10': ('{% include failed_include %}', {'failed_include': 'include-fail2'}, ('', '', template.TemplateSyntaxError)),




Expand Down Expand Up @@ -1481,8 +1487,8 @@ def get_template_tests(self):


# Failures # Failures
'old-url-fail01': ('{% url %}', {}, template.TemplateSyntaxError), 'old-url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
'old-url-fail02': ('{% url no_such_view %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)), 'old-url-fail02': ('{% url no_such_view %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
'old-url-fail03': ('{% url regressiontests.templates.views.client %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)), 'old-url-fail03': ('{% url regressiontests.templates.views.client %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
'old-url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError), 'old-url-fail04': ('{% url view id, %}', {}, template.TemplateSyntaxError),
'old-url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError), 'old-url-fail05': ('{% url view id= %}', {}, template.TemplateSyntaxError),
'old-url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError), 'old-url-fail06': ('{% url view a.id=id %}', {}, template.TemplateSyntaxError),
Expand Down Expand Up @@ -1522,18 +1528,18 @@ def get_template_tests(self):


# Failures # Failures
'url-fail01': ('{% load url from future %}{% url %}', {}, template.TemplateSyntaxError), 'url-fail01': ('{% load url from future %}{% url %}', {}, template.TemplateSyntaxError),
'url-fail02': ('{% load url from future %}{% url "no_such_view" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)), 'url-fail02': ('{% load url from future %}{% url "no_such_view" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
'url-fail03': ('{% load url from future %}{% url "regressiontests.templates.views.client" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)), 'url-fail03': ('{% load url from future %}{% url "regressiontests.templates.views.client" %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
'url-fail04': ('{% load url from future %}{% url "view" id, %}', {}, template.TemplateSyntaxError), 'url-fail04': ('{% load url from future %}{% url "view" id, %}', {}, template.TemplateSyntaxError),
'url-fail05': ('{% load url from future %}{% url "view" id= %}', {}, template.TemplateSyntaxError), 'url-fail05': ('{% load url from future %}{% url "view" id= %}', {}, template.TemplateSyntaxError),
'url-fail06': ('{% load url from future %}{% url "view" a.id=id %}', {}, template.TemplateSyntaxError), 'url-fail06': ('{% load url from future %}{% url "view" a.id=id %}', {}, template.TemplateSyntaxError),
'url-fail07': ('{% load url from future %}{% url "view" a.id!id %}', {}, template.TemplateSyntaxError), 'url-fail07': ('{% load url from future %}{% url "view" a.id!id %}', {}, template.TemplateSyntaxError),
'url-fail08': ('{% load url from future %}{% url "view" id="unterminatedstring %}', {}, template.TemplateSyntaxError), 'url-fail08': ('{% load url from future %}{% url "view" id="unterminatedstring %}', {}, template.TemplateSyntaxError),
'url-fail09': ('{% load url from future %}{% url "view" id=", %}', {}, template.TemplateSyntaxError), 'url-fail09': ('{% load url from future %}{% url "view" id=", %}', {}, template.TemplateSyntaxError),


'url-fail11': ('{% load url from future %}{% url named_url %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)), 'url-fail11': ('{% load url from future %}{% url named_url %}', {}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
'url-fail12': ('{% load url from future %}{% url named_url %}', {'named_url': 'no_such_view'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)), 'url-fail12': ('{% load url from future %}{% url named_url %}', {'named_url': 'no_such_view'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
'url-fail13': ('{% load url from future %}{% url named_url %}', {'named_url': 'regressiontests.templates.views.client'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch, template.TemplateSyntaxError)), 'url-fail13': ('{% load url from future %}{% url named_url %}', {'named_url': 'regressiontests.templates.views.client'}, (urlresolvers.NoReverseMatch, urlresolvers.NoReverseMatch)),
'url-fail14': ('{% load url from future %}{% url named_url id, %}', {'named_url': 'view'}, template.TemplateSyntaxError), 'url-fail14': ('{% load url from future %}{% url named_url id, %}', {'named_url': 'view'}, template.TemplateSyntaxError),
'url-fail15': ('{% load url from future %}{% url named_url id= %}', {'named_url': 'view'}, template.TemplateSyntaxError), 'url-fail15': ('{% load url from future %}{% url named_url id= %}', {'named_url': 'view'}, template.TemplateSyntaxError),
'url-fail16': ('{% load url from future %}{% url named_url a.id=id %}', {'named_url': 'view'}, template.TemplateSyntaxError), 'url-fail16': ('{% load url from future %}{% url named_url a.id=id %}', {'named_url': 'view'}, template.TemplateSyntaxError),
Expand Down
2 changes: 1 addition & 1 deletion tests/regressiontests/views/tests/debug.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def test_template_exceptions(self):
for n in range(len(except_args)): for n in range(len(except_args)):
try: try:
self.client.get(reverse('template_exception', args=(n,))) self.client.get(reverse('template_exception', args=(n,)))
except TemplateSyntaxError, e: except Exception:
raising_loc = inspect.trace()[-1][-2][0].strip() raising_loc = inspect.trace()[-1][-2][0].strip()
self.assertFalse(raising_loc.find('raise BrokenException') == -1, self.assertFalse(raising_loc.find('raise BrokenException') == -1,
"Failed to find 'raise BrokenException' in last frame of traceback, instead found: %s" % "Failed to find 'raise BrokenException' in last frame of traceback, instead found: %s" %
Expand Down

0 comments on commit 4397c58

Please sign in to comment.