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 %} - - - {%else%} - - - {%endifequal%} - {%endfor%} -
{{source_line.0}} {{before}}{{during}}{{after}}
{{source_line.0}} {{source_line.1}}
- - {%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; }