diff --git a/django/contrib/admin/templates/admin/template_debug.html b/django/contrib/admin/templates/admin/template_debug.html
deleted file mode 100644
index d0fdf96ee1..0000000000
--- a/django/contrib/admin/templates/admin/template_debug.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "admin/base_site" %}
-{% load adminmedia %}
-{% load i18n %}
-{% block extrahead%} {%endblock%}
-{% block content %}
-
-
{%trans "Error in Template" %}
-
-{%blocktrans %}
-In template {{name}}, error at line {{line}}:
-{%endblocktrans %}
-{{message|escape}}
-{{traceback|escape}}
-
- {%if top%}
- ...
- {%endif%}
-
-
- {% for source_line in source_lines %}
- {%ifequal source_line.0 line %}
- {{source_line.0}} |
- {{before}}{{during}}{{after}} |
- {%else%}
- {{source_line.0}} |
- {{source_line.1}} |
- {%endifequal%}
- {%endfor%}
-
-
- {%ifnotequal bottom total%}
- ...
- {%endifnotequal%}
-
-
-
-{% endblock %}
\ No newline at end of file
diff --git a/django/core/template/__init__.py b/django/core/template/__init__.py
index e7ce2de8ba..a6fde1cf73 100644
--- a/django/core/template/__init__.py
+++ b/django/core/template/__init__.py
@@ -825,16 +825,11 @@ class DebugNodeList(NodeList):
if not hasattr(e, 'source'):
e.source = node.source
raise
- except Exception, e:
- from traceback import extract_tb, format_list, format_exception_only
+ except Exception:
from sys import exc_info
- t,v,tb = exc_info()
- frames = extract_tb(tb)
- frames.pop(0)
- wrapped = TemplateSyntaxError( 'Caught exception:\n %s'
- % "".join(format_exception_only(t,v)).replace('\n',''))
+ wrapped = TemplateSyntaxError( 'Caught exception whilst rendering' )
wrapped.source = node.source
- wrapped.traceback = "".join(format_list(frames))
+ wrapped.exc_info = exc_info()
raise wrapped
return result
diff --git a/django/core/template/defaultfilters.py b/django/core/template/defaultfilters.py
index 7f891af5ba..3a25add5e1 100644
--- a/django/core/template/defaultfilters.py
+++ b/django/core/template/defaultfilters.py
@@ -200,7 +200,6 @@ def dictsort(value, arg):
Takes a list of dicts, returns that list sorted by the property given in
the argument.
"""
- print "ds:", type(value)
decorated = [(resolve_variable('var.' + arg, {'var' : item}), item) for item in value]
decorated.sort()
return [item[1] for item in decorated]
diff --git a/django/middleware/template_debug.py b/django/middleware/template_debug.py
deleted file mode 100644
index 14da1cb18b..0000000000
--- a/django/middleware/template_debug.py
+++ /dev/null
@@ -1,56 +0,0 @@
-class TemplateDebugMiddleware(object):
- def linebreak_iter(self, template_source):
- import re
- newline_re = re.compile("^", re.M)
- for match in newline_re.finditer(template_source):
- yield match.start()
- yield len(template_source) + 1
-
- def process_exception(self, request, exception):
- from django.core.template.loader import render_to_string
- from django.utils.html import escape
- from django.utils.httpwrappers import HttpResponseServerError
- from django.core.extensions import DjangoContext
- from itertools import count, izip
-
- context_lines = 10
- if hasattr(exception, 'source'):
- origin, (start, end) = exception.source
- template_source = origin.reload()
-
- line = 0
- upto = 0
- source_lines = []
- linebreaks = izip(count(0), self.linebreak_iter(template_source))
- linebreaks.next() # skip the nothing before initial line start
- for num, next in linebreaks:
- if start >= upto and end <= next :
- line = num
- before = escape(template_source[upto:start])
- during = escape(template_source[start:end])
- after = escape(template_source[end:next - 1])
-
- source_lines.append( (num, escape(template_source[upto:next - 1])) )
- upto = next
-
- total = len(source_lines)
-
- top = max(0, line - context_lines)
- bottom = min(total, line + 1 + context_lines)
- traceback = hasattr(exception, 'traceback') and exception.traceback or ''
- result = render_to_string('template_debug',
- DjangoContext(request, {
- 'message' : exception.args[0],
- 'traceback' : traceback,
- 'source_lines' : source_lines[top:bottom],
- 'before' : before,
- 'during': during,
- 'after': after,
- 'top': top ,
- 'bottom': bottom ,
- 'total' : total,
- 'line' : line,
- 'name' : origin.name,
- }),
- )
- return HttpResponseServerError(result)
diff --git a/django/views/debug.py b/django/views/debug.py
index 4aece9443d..96e8594fb1 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -6,14 +6,65 @@ from django.conf import settings
from os.path import dirname, join as pathjoin
from django.core.template import Template, Context
from django.utils.httpwrappers import HttpResponseServerError, HttpResponseNotFound
+from itertools import count, izip
+from django.utils.html import escape
HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD')
+def linebreak_iter(template_source):
+ import re
+ newline_re = re.compile("^", re.M)
+ for match in newline_re.finditer(template_source):
+ yield match.start()
+ yield len(template_source) + 1
+
+def get_template_exception_info(exc_type,exc_value,tb):
+ origin, (start, end) = exc_value.source
+ template_source = origin.reload()
+ context_lines = 10
+ line = 0
+ upto = 0
+ source_lines = []
+ linebreaks = izip(count(0), linebreak_iter(template_source))
+ linebreaks.next() # skip the nothing before initial line start
+ for num, next in linebreaks:
+ if start >= upto and end <= next :
+ line = num
+ before = escape(template_source[upto:start])
+ during = escape(template_source[start:end])
+ after = escape(template_source[end:next - 1])
+
+ source_lines.append( (num, escape(template_source[upto:next - 1])) )
+ upto = next
+
+ total = len(source_lines)
+
+ top = max(0, line - context_lines)
+ bottom = min(total, line + 1 + context_lines)
+
+ template_info = {
+ 'message' : exc_value.args[0],
+ 'source_lines' : source_lines[top:bottom],
+ 'before' : before,
+ 'during': during,
+ 'after': after,
+ 'top': top ,
+ 'bottom': bottom ,
+ 'total' : total,
+ 'line' : line,
+ 'name' : origin.name,
+ }
+ exc_info = hasattr(exc_value, 'exc_info') and exc_value.exc_info or (exc_type,exc_value,tb)
+ return exc_info + (template_info,)
+
def technical_500_response(request, exc_type, exc_value, tb):
"""
Create a technical server error response. The last three arguments are
the values returned from sys.exc_info() and friends.
"""
+ template_info = None
+ if settings.TEMPLATE_DEBUG and hasattr(exc_value, 'source'):
+ exc_type, exc_value, tb, template_info = get_template_exception_info(exc_type,exc_value,tb)
frames = []
while tb is not None:
filename = tb.tb_frame.f_code.co_filename
@@ -53,7 +104,7 @@ def technical_500_response(request, exc_type, exc_value, tb):
'request' : request,
'request_protocol' : os.environ.get("HTTPS") == "on" and "https" or "http",
'settings' : settings_dict,
-
+ 'template_info': template_info,
})
return HttpResponseServerError(t.render(c))
@@ -144,6 +195,9 @@ TECHNICAL_500_TEMPLATE = """
#summary table { border:none; background:transparent; }
#requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; }
#requestinfo h3 { margin-bottom:-1em; }
+ table.source td{ font-family: monospace; white-space: pre;}
+ span.specific{background:#ffcab7;}
+ .error { background:#ffc; }