mirror of
https://github.com/django/django.git
synced 2025-07-05 02:09:13 +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:
parent
58f4007b55
commit
1e945cb8fa
@ -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 %}
|
@ -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
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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)
|
@ -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">
|
||||
|
Loading…
x
Reference in New Issue
Block a user