from django.conf import settings from django.core.template import Template, Context from django.utils.html import escape from django.utils.httpwrappers import HttpResponseServerError, HttpResponseNotFound import inspect, os, re, sys from itertools import count, izip from os.path import dirname, join as pathjoin HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD') def linebreak_iter(template_source): p = template_source.find('\n') while p >= 0: yield p p = template_source.find('\n', p+1) 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 function = tb.tb_frame.f_code.co_name lineno = tb.tb_lineno - 1 pre_context_lineno, pre_context, context_line, post_context = _get_lines_from_file(filename, lineno, 7) frames.append({ 'tb': tb, 'filename': filename, 'function': function, 'lineno': lineno, 'vars': tb.tb_frame.f_locals.items(), 'id': id(tb), 'pre_context': pre_context, 'context_line': context_line, 'post_context': post_context, 'pre_context_lineno': pre_context_lineno, }) tb = tb.tb_next # Turn the settings module into a dict, filtering out anything that # matches HIDDEN_SETTINGS along the way. settings_dict = {} for k in dir(settings): if k.isupper(): if HIDDEN_SETTINGS.search(k): settings_dict[k] = '********************' else: settings_dict[k] = getattr(settings, k) t = Template(TECHNICAL_500_TEMPLATE) c = Context({ 'exception_type': exc_type.__name__, 'exception_value': exc_value, 'frames': frames, 'lastframe': frames[-1], '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), mimetype='text/html') def technical_404_response(request, exception): """ Create a technical 404 error response. The exception should be the Http404 exception. """ try: tried = exception.args[0]['tried'] except (IndexError, TypeError): tried = [] t = Template(TECHNICAL_404_TEMPLATE) c = Context({ 'root_urlconf': settings.ROOT_URLCONF, 'urlpatterns': tried, 'reason': str(exception), 'request': request, 'request_protocol': os.environ.get("HTTPS") == "on" and "https" or "http", 'settings': dict([(k, getattr(settings, k)) for k in dir(settings) if k.isupper()]), }) return HttpResponseNotFound(t.render(c), mimetype='text/html') def _get_lines_from_file(filename, lineno, context_lines): """ Returns context_lines before and after lineno from file. Returns (pre_context_lineno, pre_context, context_line, post_context). """ try: source = open(filename).readlines() lower_bound = max(0, lineno - context_lines) upper_bound = lineno + context_lines pre_context = [line.strip('\n') for line in source[lower_bound:lineno]] context_line = source[lineno].strip('\n') post_context = [line.strip('\n') for line in source[lineno+1:upper_bound]] return lower_bound, pre_context, context_line, post_context except (OSError, IOError): return None, [], None, [] # # Templates are embedded in the file so that we know the error handler will # always work even if the template loader is broken. # TECHNICAL_500_TEMPLATE = """ {{ exception_type }} at {{ request.path }}

{{ exception_type }} at {{ request.path }}

{{ exception_value }}

Request Method: {{ request.META.REQUEST_METHOD }}
Request URL: {{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path }}
Exception Type: {{ exception_type }}
Exception Value: {{ exception_value }}
Exception Location: {{ lastframe.filename }} in {{ lastframe.function }}, line {{ lastframe.lineno }}
{% if template_info %}

Template error

In template {{ template_info.name }}, error at line {{ template_info.line }}

{{ template_info.message|escape }}

{% for source_line in template_info.source_lines %} {% ifequal source_line.0 template_info.line %} {% else %} {% endifequal %} {% endfor %}
{{ source_line.0 }} {{ template_info.before }}{{ template_info.during }}{{ template_info.after }}
{{ source_line.0 }} {{ source_line.1 }}
{% endif %}

Traceback (innermost last)

Request information

GET

{% if request.GET %} {% for var in request.GET.items %} {% endfor %}
Variable Value
{{ var.0 }}
{{ var.1|pprint|escape }}
{% else %}

No GET data

{% endif %}

POST

{% if request.POST %} {% for var in request.POST.items %} {% endfor %}
Variable Value
{{ var.0 }}
{{ var.1|pprint|escape }}
{% else %}

No POST data

{% endif %} {% if request.COOKIES %} {% for var in request.COOKIES.items %} {% endfor %}
Variable Value
{{ var.0 }}
{{ var.1|pprint|escape }}
{% else %}

No cookie data

{% endif %}

META

{% for var in request.META.items|dictsort:"0" %} {% endfor %}
Variable Value
{{ var.0 }}
{{ var.1|pprint|escape }}

Settings

Using settings module {{ settings.SETTINGS_MODULE }}

{% for var in settings.items|dictsort:"0" %} {% endfor %}
Setting Value
{{ var.0 }}
{{ var.1|pprint|escape }}

You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 500 page.

""" TECHNICAL_404_TEMPLATE = """ Page not found at {{ request.path }}

Page not found (404)

Request Method: {{ request.META.REQUEST_METHOD }}
Request URL: {{ request_protocol }}://{{ request.META.HTTP_HOST }}{{ request.path }}
{% if urlpatterns %}

Using the URLconf defined in {{ settings.ROOT_URLCONF }}, Django tried these URL patterns, in this order:

    {% for pattern in urlpatterns %}
  1. {{ pattern|escape }}
  2. {% endfor %}

The current URL, {{ request.path }}, didn't match any of these.

{% else %}

{{ reason|escape }}

{% endif %}

You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

"""