Fixed #27584 -- Fixed display of render time template errors.

This commit is contained in:
Preston Timmons 2016-12-13 20:35:21 -06:00 committed by Tim Graham
parent 5e239ae907
commit 0b4d517263
6 changed files with 45 additions and 5 deletions

View File

@ -200,16 +200,13 @@ class Template(object):
def render(self, context): def render(self, context):
"Display stage -- can be called many times" "Display stage -- can be called many times"
context.render_context.push() with context.render_context.push_state(self):
try:
if context.template is None: if context.template is None:
with context.bind_template(self): with context.bind_template(self):
context.template_name = self.name context.template_name = self.name
return self._render(context) return self._render(context)
else: else:
return self._render(context) return self._render(context)
finally:
context.render_context.pop()
def compile_nodelist(self): def compile_nodelist(self):
""" """
@ -960,7 +957,7 @@ class Node(object):
return self.render(context) return self.render(context)
except Exception as e: except Exception as e:
if context.template.engine.debug and not hasattr(e, 'template_debug'): if context.template.engine.debug and not hasattr(e, 'template_debug'):
e.template_debug = context.template.get_exception_info(e, self.token) e.template_debug = context.render_context.template.get_exception_info(e, self.token)
raise raise
def __iter__(self): def __iter__(self):

View File

@ -199,6 +199,8 @@ class RenderContext(BaseContext):
rendering of other templates as they would if they were stored in the normal rendering of other templates as they would if they were stored in the normal
template context. template context.
""" """
template = None
def __iter__(self): def __iter__(self):
for d in self.dicts[-1]: for d in self.dicts[-1]:
yield d yield d
@ -212,6 +214,17 @@ class RenderContext(BaseContext):
def __getitem__(self, key): def __getitem__(self, key):
return self.dicts[-1][key] return self.dicts[-1][key]
@contextmanager
def push_state(self, template):
initial = self.template
self.template = template
self.push()
try:
yield
finally:
self.template = initial
self.pop()
class RequestContext(Context): class RequestContext(Context):
""" """

View File

@ -0,0 +1,3 @@
{% load tag_27584 %}
{% badtag %}{% endbadtag %}

View File

@ -0,0 +1 @@
{% include "27584_child.html" %}

View File

@ -0,0 +1,15 @@
from django import template
register = template.Library()
@register.tag
def badtag(parser, token):
parser.parse(('endbadtag',))
parser.delete_first_token()
return BadNode()
class BadNode(template.Node):
def render(self, context):
raise template.TemplateSyntaxError('error')

View File

@ -114,6 +114,17 @@ class TemplateTests(SimpleTestCase):
engine.from_string("{% load bad_tag %}{% badtag %}") engine.from_string("{% load bad_tag %}{% badtag %}")
self.assertEqual(e.exception.template_debug['during'], '{% badtag %}') self.assertEqual(e.exception.template_debug['during'], '{% badtag %}')
def test_compile_tag_error_27584(self):
engine = Engine(
app_dirs=True,
debug=True,
libraries={'tag_27584': 'template_tests.templatetags.tag_27584'},
)
t = engine.get_template('27584_parent.html')
with self.assertRaises(TemplateSyntaxError) as e:
t.render(Context())
self.assertEqual(e.exception.template_debug['during'], '{% badtag %}')
def test_super_errors(self): def test_super_errors(self):
""" """
#18169 -- NoReverseMatch should not be silence in block.super. #18169 -- NoReverseMatch should not be silence in block.super.