1
0
mirror of https://github.com/django/django.git synced 2025-07-05 10:19:20 +00:00

Integrated template errors into new error pages.

git-svn-id: http://code.djangoproject.com/svn/django/branches/new-admin@1299 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Robert Wittams 2005-11-20 15:38:14 +00:00
parent 58f4007b55
commit 1e945cb8fa
5 changed files with 76 additions and 104 deletions

View File

@ -1,37 +0,0 @@
{% extends "admin/base_site" %}
{% load adminmedia %}
{% load i18n %}
{% block extrahead%} <link rel="stylesheet" type="text/css" href="{% admin_media_prefix %}css/template_errors.css" /> {%endblock%}
{% block content %}
<div>
<h2>{%trans "Error in Template" %}</h2>
<pre>
{%blocktrans %}
In template {{name}}, error at line {{line}}:
{%endblocktrans %}
{{message|escape}}
{{traceback|escape}}
</pre>
{%if top%}
...
{%endif%}
<table class="source{%if top%} cut-top{%endif%}{%ifnotequal bottom total%} cut-bottom{%endifnotequal%}">
{% for source_line in source_lines %}
{%ifequal source_line.0 line %}
<tr class="error"><td>{{source_line.0}}</td>
<td> {{before}}<span class="specific">{{during}}</span>{{after}}</td></tr>
{%else%}
<tr><td>{{source_line.0}}</td>
<td> {{source_line.1}}</td></tr>
{%endifequal%}
{%endfor%}
</table>
{%ifnotequal bottom total%}
...
{%endifnotequal%}
</div>
{% endblock %}

View File

@ -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

View File

@ -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]

View File

@ -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)

View File

@ -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; }
</style>
<script type="text/javascript">
//<!--
@ -221,7 +275,24 @@ TECHNICAL_500_TEMPLATE = """
</tr>
</table>
</div>
{%if template_info %}
<div id="template">
<h2>Template</h2>
In template {{template_info.name}}, error at line {{template_info.line}}
<div>{{template_info.message|escape}}</div>
<table class="source{%if template_info.top%} cut-top{%endif%}{%ifnotequal template_info.bottom template_info.total%} cut-bottom{%endifnotequal%}">
{% for source_line in template_info.source_lines %}
{%ifequal source_line.0 template_info.line %}
<tr class="error"><td>{{source_line.0}}</td>
<td> {{template_info.before}}<span class="specific">{{template_info.during}}</span>{{template_info.after}}</td></tr>
{%else%}
<tr><td>{{source_line.0}}</td>
<td> {{source_line.1}}</td></tr>
{%endifequal%}
{%endfor%}
</table>
</div>
{%endif%}
<div id="traceback">
<h2>Traceback <span>(innermost last)</span></h2>
<ul class="traceback">