Code

Ticket #16770: unwrap_templatesyntaxerror.diff

File unwrap_templatesyntaxerror.diff, 7.4 KB (added by jMyles, 3 years ago)

OK, this patch is feeling a little more final. I have some concerns about the fact that there seems to be no branch whatsoever that causes execution of the except block of line 79 of the template/debug. I'll get confirmation.

Line 
1Index: django/views/debug.py
2===================================================================
3--- django/views/debug.py       (revision 16730)
4+++ django/views/debug.py       (working copy)
5@@ -223,8 +223,7 @@
6                     'loader': loader_name,
7                     'templates': template_list,
8                 })
9-        if (settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source') and
10-            isinstance(self.exc_value, TemplateSyntaxError)):
11+        if (settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source_template_node')):
12             self.get_template_exception_info()
13 
14         frames = self.get_traceback_frames()
15@@ -268,7 +267,7 @@
16         return t.render(c)
17 
18     def get_template_exception_info(self):
19-        origin, (start, end) = self.exc_value.source
20+        origin, (start, end) = self.exc_value.source_template_node
21         template_source = origin.reload()
22         context_lines = 10
23         line = 0
24@@ -626,7 +625,7 @@
25 {% endif %}
26 {% if template_info %}
27 <div id="template">
28-   <h2>Template error</h2>
29+   <h2>Error occured during template rendering</h2>
30    <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
31    <h3>{{ template_info.message }}</h3>
32    <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}">
33Index: django/template/debug.py
34===================================================================
35--- django/template/debug.py    (revision 16730)
36+++ django/template/debug.py    (working copy)
37@@ -4,6 +4,7 @@
38 from django.utils.safestring import SafeData, EscapeData
39 from django.utils.formats import localize
40 
41+
42 class DebugLexer(Lexer):
43     def __init__(self, template_string, origin):
44         super(DebugLexer, self).__init__(template_string, origin)
45@@ -42,9 +43,9 @@
46     def error(self, token, msg):
47         return self.source_error(token.source, msg)
48 
49-    def source_error(self, source,msg):
50+    def source_error(self, source, msg):
51         e = TemplateSyntaxError(msg)
52-        e.source = source
53+        e.source_template_node = source #Identify the template node that was being rendered when the error occurred.
54         return e
55 
56     def create_nodelist(self):
57@@ -67,20 +68,21 @@
58             e.source = token.source
59 
60 class DebugNodeList(NodeList):
61+    '''
62+    A list of nodes that is instantiated when debug is True - this is the nerve center of exceptions that occur during template rendering.
63+    '''
64     def render_node(self, node, context):
65         try:
66             result = node.render(context)
67         except TemplateSyntaxError, e:
68-            if not hasattr(e, 'source'):
69-                e.source = node.source
70-            raise
71+            if not hasattr(e, 'source_template_node'): #Have we already identified the node where the problem occured?
72+                e.source_template_node = node.source #...if so, let's annotate the exception with that.
73+            raise       
74         except Exception, e:
75             from sys import exc_info
76-            wrapped = TemplateSyntaxError(u'Caught %s while rendering: %s' %
77-                (e.__class__.__name__, force_unicode(e, errors='replace')))
78-            wrapped.source = getattr(e, 'template_node_source', node.source)
79-            wrapped.exc_info = exc_info()
80-            raise wrapped, None, wrapped.exc_info[2]
81+            e.source_template_node = getattr(e, 'template_node_source', node.source) #Again, annotating the exception with the node
82+            e.exc_info = exc_info()
83+            raise e, None, e.exc_info[2] #Make sure that ExceptionReporter gets the traceback
84         return result
85 
86 class DebugVariableNode(VariableNode):
87Index: django/views/debug.py
88===================================================================
89--- django/views/debug.py       (revision 16741)
90+++ django/views/debug.py       (working copy)
91@@ -223,8 +223,7 @@
92                     'loader': loader_name,
93                     'templates': template_list,
94                 })
95-        if (settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source') and
96-            isinstance(self.exc_value, TemplateSyntaxError)):
97+        if (settings.TEMPLATE_DEBUG and hasattr(self.exc_value, 'source_template_node')):
98             self.get_template_exception_info()
99 
100         frames = self.get_traceback_frames()
101@@ -268,7 +267,7 @@
102         return t.render(c)
103 
104     def get_template_exception_info(self):
105-        origin, (start, end) = self.exc_value.source
106+        origin, (start, end) = self.exc_value.source_template_node
107         template_source = origin.reload()
108         context_lines = 10
109         line = 0
110@@ -626,7 +625,7 @@
111 {% endif %}
112 {% if template_info %}
113 <div id="template">
114-   <h2>Template error</h2>
115+   <h2>Error occured during template rendering</h2>
116    <p>In template <code>{{ template_info.name }}</code>, error at line <strong>{{ template_info.line }}</strong></p>
117    <h3>{{ template_info.message }}</h3>
118    <table class="source{% if template_info.top %} cut-top{% endif %}{% ifnotequal template_info.bottom template_info.total %} cut-bottom{% endifnotequal %}">
119Index: django/template/debug.py
120===================================================================
121--- django/template/debug.py    (revision 16741)
122+++ django/template/debug.py    (working copy)
123@@ -4,6 +4,7 @@
124 from django.utils.safestring import SafeData, EscapeData
125 from django.utils.formats import localize
126 
127+
128 class DebugLexer(Lexer):
129     def __init__(self, template_string, origin):
130         super(DebugLexer, self).__init__(template_string, origin)
131@@ -42,9 +43,9 @@
132     def error(self, token, msg):
133         return self.source_error(token.source, msg)
134 
135-    def source_error(self, source,msg):
136+    def source_error(self, source, msg):
137         e = TemplateSyntaxError(msg)
138-        e.source = source
139+        e.source_template_node = source #Identify the template node that was being rendered when the error occurred.
140         return e
141 
142     def create_nodelist(self):
143@@ -67,20 +68,21 @@
144             e.source = token.source
145 
146 class DebugNodeList(NodeList):
147+    '''
148+    A list of nodes that is instantiated when debug is True - this is the nerve center of exceptions that occur during template rendering.
149+    '''
150     def render_node(self, node, context):
151         try:
152             result = node.render(context)
153         except TemplateSyntaxError, e:
154-            if not hasattr(e, 'source'):
155-                e.source = node.source
156-            raise
157+            if not hasattr(e, 'source_template_node'): #Have we already identified the node where the problem occured?
158+                e.source_template_node = node.source #...if so, let's annotate the exception with that.
159+            raise       
160         except Exception, e:
161             from sys import exc_info
162-            wrapped = TemplateSyntaxError(u'Caught %s while rendering: %s' %
163-                (e.__class__.__name__, force_unicode(e, errors='replace')))
164-            wrapped.source = getattr(e, 'template_node_source', node.source)
165-            wrapped.exc_info = exc_info()
166-            raise wrapped, None, wrapped.exc_info[2]
167+            e.source_template_node = getattr(e, 'template_node_source', node.source) #Again, annotating the exception with the node
168+            e.exc_info = exc_info()
169+            raise e, None, e.exc_info[2] #Make sure that ExceptionReporter gets the traceback
170         return result
171 
172 class DebugVariableNode(VariableNode):