mirror of https://github.com/django/django.git
Fixed #19819 - Improved template filter errors handling.
Wrap the Parser.compile_filter method call with a try/except and call the newly added Parser.compile_filter_error(). Overwrite this method in the DebugParser to throw the correct error. Since this error was otherwise catched by the compile_function try/except block the debugger highlighted the wrong line.
This commit is contained in:
parent
f1029b308f
commit
138de533ff
|
@ -250,7 +250,11 @@ class Parser(object):
|
||||||
elif token.token_type == 1: # TOKEN_VAR
|
elif token.token_type == 1: # TOKEN_VAR
|
||||||
if not token.contents:
|
if not token.contents:
|
||||||
self.empty_variable(token)
|
self.empty_variable(token)
|
||||||
filter_expression = self.compile_filter(token.contents)
|
try:
|
||||||
|
filter_expression = self.compile_filter(token.contents)
|
||||||
|
except TemplateSyntaxError as e:
|
||||||
|
if not self.compile_filter_error(token, e):
|
||||||
|
raise
|
||||||
var_node = self.create_variable_node(filter_expression)
|
var_node = self.create_variable_node(filter_expression)
|
||||||
self.extend_nodelist(nodelist, var_node, token)
|
self.extend_nodelist(nodelist, var_node, token)
|
||||||
elif token.token_type == 2: # TOKEN_BLOCK
|
elif token.token_type == 2: # TOKEN_BLOCK
|
||||||
|
@ -330,6 +334,9 @@ class Parser(object):
|
||||||
def unclosed_block_tag(self, parse_until):
|
def unclosed_block_tag(self, parse_until):
|
||||||
raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until))
|
raise self.error(None, "Unclosed tags: %s " % ', '.join(parse_until))
|
||||||
|
|
||||||
|
def compile_filter_error(self, token, e):
|
||||||
|
pass
|
||||||
|
|
||||||
def compile_function_error(self, token, e):
|
def compile_function_error(self, token, e):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,10 @@ class DebugParser(Parser):
|
||||||
msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
|
msg = "Unclosed tag '%s'. Looking for one of: %s " % (command, ', '.join(parse_until))
|
||||||
raise self.source_error(source, msg)
|
raise self.source_error(source, msg)
|
||||||
|
|
||||||
|
def compile_filter_error(self, token, e):
|
||||||
|
if not hasattr(e, 'django_template_source'):
|
||||||
|
e.django_template_source = token.source
|
||||||
|
|
||||||
def compile_function_error(self, token, e):
|
def compile_function_error(self, token, e):
|
||||||
if not hasattr(e, 'django_template_source'):
|
if not hasattr(e, 'django_template_source'):
|
||||||
e.django_template_source = token.source
|
e.django_template_source = token.source
|
||||||
|
|
|
@ -4,8 +4,10 @@ Testing some internals of the template processing. These are *not* examples to b
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.template import (TokenParser, FilterExpression, Parser, Variable,
|
from django.template import (TokenParser, FilterExpression, Parser, Variable,
|
||||||
TemplateSyntaxError)
|
Template, TemplateSyntaxError)
|
||||||
|
from django.test.utils import override_settings
|
||||||
from django.utils.unittest import TestCase
|
from django.utils.unittest import TestCase
|
||||||
|
from django.utils import six
|
||||||
|
|
||||||
|
|
||||||
class ParserTests(TestCase):
|
class ParserTests(TestCase):
|
||||||
|
@ -83,3 +85,11 @@ class ParserTests(TestCase):
|
||||||
self.assertRaises(TemplateSyntaxError,
|
self.assertRaises(TemplateSyntaxError,
|
||||||
Variable, "article._hidden"
|
Variable, "article._hidden"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@override_settings(DEBUG=True, TEMPLATE_DEBUG=True)
|
||||||
|
def test_compile_filter_error(self):
|
||||||
|
# regression test for #19819
|
||||||
|
msg = "Could not parse the remainder: '@bar' from 'foo@bar'"
|
||||||
|
with six.assertRaisesRegex(self, TemplateSyntaxError, msg) as cm:
|
||||||
|
Template("{% if 1 %}{{ foo@bar }}{% endif %}")
|
||||||
|
self.assertEqual(cm.exception.django_template_source[1], (10, 23))
|
||||||
|
|
Loading…
Reference in New Issue