Fixed #28935 -- Fixed display of errors in extended blocks.

Get the template that caused the exception and get the
exception info from that template, using the node that
caused the exception.
This commit is contained in:
cammil 2021-05-07 21:49:07 +01:00 committed by Mariusz Felisiak
parent 9f3cce172f
commit 313c3d1aa1
4 changed files with 30 additions and 3 deletions

View File

@ -926,8 +926,17 @@ class Node:
try:
return self.render(context)
except Exception as e:
if context.template.engine.debug and not hasattr(e, 'template_debug'):
e.template_debug = context.render_context.template.get_exception_info(e, self.token)
if context.template.engine.debug:
# Store the actual node that caused the exception.
if not hasattr(e, '_culprit_node'):
e._culprit_node = self
if (
not hasattr(e, 'template_debug') and
context.render_context.template.origin == e._culprit_node.origin
):
e.template_debug = context.render_context.template.get_exception_info(
e, e._culprit_node.token,
)
raise
def __iter__(self):

View File

@ -0,0 +1,2 @@
{% extends "test_extends_block_error_parent.html" %}
{% block content %}{% include "missing.html" %}{% endblock %}

View File

@ -0,0 +1 @@
{% block content %}{% endblock %}

View File

@ -1,11 +1,14 @@
import sys
from django.contrib.auth.models import Group
from django.template import Context, Engine, TemplateSyntaxError
from django.template import (
Context, Engine, TemplateDoesNotExist, TemplateSyntaxError,
)
from django.template.base import UNKNOWN_SOURCE
from django.test import SimpleTestCase, override_settings
from django.urls import NoReverseMatch
from django.utils import translation
from django.utils.html import escape
class TemplateTests(SimpleTestCase):
@ -134,6 +137,18 @@ class TemplateTests(SimpleTestCase):
t.render(Context())
self.assertEqual(e.exception.template_debug['during'], '{% badtag %}')
def test_render_tag_error_in_extended_block(self):
"""Errors in extended block are displayed correctly."""
e = Engine(app_dirs=True, debug=True)
template = e.get_template('test_extends_block_error.html')
context = Context()
with self.assertRaises(TemplateDoesNotExist) as cm:
template.render(context)
self.assertEqual(
cm.exception.template_debug['during'],
escape('{% include "missing.html" %}'),
)
def test_super_errors(self):
"""
#18169 -- NoReverseMatch should not be silence in block.super.