1
0
mirror of https://github.com/django/django.git synced 2025-10-31 09:41:08 +00:00

Fixed #16770 -- Eliminated TemplateSyntaxError wrapping of exceptions. 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
This commit is contained in:
Carl Meyer
2011-09-16 01:16:25 +00:00
parent 608548baa2
commit 4397c587a4
6 changed files with 69 additions and 78 deletions

View File

@@ -4,6 +4,7 @@ from django.utils.html import escape
from django.utils.safestring import SafeData, EscapeData
from django.utils.formats import localize
class DebugLexer(Lexer):
def __init__(self, template_string, origin):
super(DebugLexer, self).__init__(template_string, origin)
@@ -42,9 +43,9 @@ class DebugParser(Parser):
def error(self, token, msg):
return self.source_error(token.source, msg)
def source_error(self, source,msg):
def source_error(self, source, msg):
e = TemplateSyntaxError(msg)
e.source = source
e.django_template_source = source
return e
def create_nodelist(self):
@@ -63,25 +64,18 @@ class DebugParser(Parser):
raise self.source_error(source, msg)
def compile_function_error(self, token, e):
if not hasattr(e, 'source'):
e.source = token.source
if not hasattr(e, 'django_template_source'):
e.django_template_source = token.source
class DebugNodeList(NodeList):
def render_node(self, node, context):
try:
result = node.render(context)
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = node.source
raise
return node.render(context)
except Exception, e:
from sys import exc_info
wrapped = TemplateSyntaxError(u'Caught %s while rendering: %s' %
(e.__class__.__name__, force_unicode(e, errors='replace')))
wrapped.source = getattr(e, 'template_node_source', node.source)
wrapped.exc_info = exc_info()
raise wrapped, None, wrapped.exc_info[2]
return result
if not hasattr(e, 'django_template_source'):
e.django_template_source = node.source
raise
class DebugVariableNode(VariableNode):
def render(self, context):
@@ -89,12 +83,12 @@ class DebugVariableNode(VariableNode):
output = self.filter_expression.resolve(context)
output = localize(output, use_l10n=context.use_l10n)
output = force_unicode(output)
except TemplateSyntaxError, e:
if not hasattr(e, 'source'):
e.source = self.source
raise
except UnicodeDecodeError:
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):
return escape(output)
else:

View File

@@ -227,17 +227,15 @@ class ForNode(Node):
context.update(unpacked_vars)
else:
context[self.loopvars[0]] = item
# In TEMPLATE_DEBUG mode providing source of the node which
# actually raised an exception to DefaultNodeList.render_node
# In TEMPLATE_DEBUG mode provide source of the node which
# actually raised the exception
if settings.TEMPLATE_DEBUG:
for node in self.nodelist_loop:
try:
nodelist.append(node.render(context))
except Exception, e:
if not hasattr(e, 'template_node_source'):
from sys import exc_info
e.template_node_source = node.source
raise e, None, exc_info()[2]
if not hasattr(e, 'django_template_source'):
e.django_template_source = node.source
raise
else:
for node in self.nodelist_loop: