Ticket #10841: 10841.3.diff

File 10841.3.diff, 8.5 KB (added by Ramiro Morales, 13 years ago)

Patch updated to current code status in trunk

  • django/views/debug.py

    diff --git a/django/views/debug.py b/django/views/debug.py
    a b  
    5959    the values returned from sys.exc_info() and friends.
    6060    """
    6161    reporter = ExceptionReporter(request, exc_type, exc_value, tb)
    62     html = reporter.get_traceback_html()
    63     return HttpResponseServerError(html, mimetype='text/html')
     62    if request.is_ajax():
     63        text = reporter.get_traceback_text()
     64        return HttpResponseServerError(text, mimetype='text/plain')
     65    else:
     66        html = reporter.get_traceback_html()
     67        return HttpResponseServerError(html, mimetype='text/html')
    6468
    6569# Cache for the default exception reporter filter instance.
    6670default_exception_reporter_filter = None
     
    201205            self.exc_value = Exception('Deprecated String Exception: %r' % self.exc_type)
    202206            self.exc_type = type(self.exc_value)
    203207
    204     def get_traceback_html(self):
    205         "Return HTML code for traceback."
     208    def get_traceback_data(self):
     209        "Return a Context instance containing traceback information."
    206210
    207211        if self.exc_type and issubclass(self.exc_type, TemplateDoesNotExist):
    208212            from django.template.loader import template_source_loaders
     
    240244                unicode_str = self.exc_value.args[1]
    241245                unicode_hint = smart_unicode(unicode_str[max(start-5, 0):min(end+5, len(unicode_str))], 'ascii', errors='replace')
    242246        from django import get_version
    243         t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template')
    244         c = Context({
     247        c = {
    245248            'is_email': self.is_email,
    246249            'unicode_hint': unicode_hint,
    247250            'frames': frames,
     
    256259            'template_info': self.template_info,
    257260            'template_does_not_exist': self.template_does_not_exist,
    258261            'loader_debug_info': self.loader_debug_info,
    259         })
     262        }
    260263        # Check whether exception info is available
    261264        if self.exc_type:
    262265            c['exception_type'] = self.exc_type.__name__
     
    264267            c['exception_value'] = smart_unicode(self.exc_value, errors='replace')
    265268        if frames:
    266269            c['lastframe'] = frames[-1]
     270        return c
     271
     272    def get_traceback_html(self):
     273        "Return HTML version of debug 500 HTTP error page."
     274        t = Template(TECHNICAL_500_TEMPLATE, name='Technical 500 template')
     275        c = Context(self.get_traceback_data())
     276        return t.render(c)
     277
     278    def get_traceback_text(self):
     279        "Return plain text version of debug 500 HTTP error page."
     280        t = Template(TECHNICAL_500_TEXT_TEMPLATE, name='Technical 500 template')
     281        c = Context(self.get_traceback_data(), autoescape=False)
    267282        return t.render(c)
    268283
    269284    def get_template_exception_info(self):
     
    890905</html>
    891906"""
    892907
     908TECHNICAL_500_TEXT_TEMPLATE = """{% firstof exception_type 'Report' %}{% if request %} at {{ request.path_info }}{% endif %}
     909{% firstof exception_value 'No exception supplied' %}
     910{% if request %}
     911Request Method: {{ request.META.REQUEST_METHOD }}
     912Request URL: {{ request.build_absolute_uri }}{% endif %}
     913Django Version: {{ django_version_info }}
     914Python Executable: {{ sys_executable }}
     915Python Version: {{ sys_version_info }}
     916Python Path: {{ sys_path }}
     917Server time: {{server_time|date:"r"}}
     918Installed Applications:
     919{{ settings.INSTALLED_APPS|pprint }}
     920Installed Middleware:
     921{{ settings.MIDDLEWARE_CLASSES|pprint }}
     922{% if template_does_not_exist %}Template loader Error:
     923{% if loader_debug_info %}Django tried loading these templates, in this order:
     924{% for loader in loader_debug_info %}Using loader {{ loader.loader }}:
     925{% for t in loader.templates %}{{ t.name }} (File {% if t.exists %}exists{% else %}does not exist{% endif %})
     926{% endfor %}{% endfor %}
     927{% else %}Django couldn't find any templates because your TEMPLATE_LOADERS setting is empty!
     928{% endif %}
     929{% endif %}{% if template_info %}
     930Template error:
     931In template {{ template_info.name }}, error at line {{ template_info.line }}
     932   {{ template_info.message }}{% for source_line in template_info.source_lines %}{% ifequal source_line.0 template_info.line %}
     933   {{ source_line.0 }} : {{ template_info.before }} {{ template_info.during }} {{ template_info.after }}
     934{% else %}
     935   {{ source_line.0 }} : {{ source_line.1 }}
     936   {% endifequal %}{% endfor %}{% endif %}{% if frames %}
     937Traceback:
     938{% for frame in frames %}File "{{ frame.filename }}" in {{ frame.function }}
     939{% if frame.context_line %}  {{ frame.lineno }}. {{ frame.context_line }}{% endif %}
     940{% endfor %}
     941{% if exception_type %}Exception Type: {{ exception_type }}{% if request %} at {{ request.path_info }}{% endif %}
     942{% if exception_value %}Exception Value: {{ exception_value }}{% endif %}{% endif %}{% endif %}
     943{% if request %}Request information:
     944GET:{% for k, v in request.GET.items %}
     945{{ k }} = {{ v|stringformat:"r" }}{% empty %} No GET data{% endfor %}
     946
     947POST:{% for k, v in request.POST.items %}
     948{{ k }} = {{ v|stringformat:"r" }}{% empty %} No POST data{% endfor %}
     949
     950FILES:{% for k, v in request.FILES.items %}
     951{{ k }} = {{ v|stringformat:"r" }}{% empty %} No FILES data{% endfor %}
     952
     953COOKIES:{% for k, v in request.COOKIES.items %}
     954{{ k }} = {{ v|stringformat:"r" }}{% empty %} No cookie data{% endfor %}
     955
     956META:{% for k, v in request.META.items|dictsort:"0" %}
     957{{ k }} = {{ v|stringformat:"r" }}{% endfor %}
     958{% else %}Request data not supplied
     959{% endif %}
     960Settings:
     961Using settings module {{ settings.SETTINGS_MODULE }}{% for k, v in settings.items|dictsort:"0" %}
     962{{ k }} = {{ v|stringformat:"r" }}{% endfor %}
     963
     964You're seeing this error because you have DEBUG = True in your
     965Django settings file. Change that to False, and Django will
     966display a standard 500 page.
     967"""
     968
    893969TECHNICAL_404_TEMPLATE = """
    894970<!DOCTYPE html>
    895971<html lang="en">
  • tests/regressiontests/views/tests/debug.py

    diff --git a/tests/regressiontests/views/tests/debug.py b/tests/regressiontests/views/tests/debug.py
    a b  
    171171        self.assertIn('<p>Request data not supplied</p>', html)
    172172
    173173
     174class PlainTextReportTests(TestCase):
     175    rf = RequestFactory()
     176
     177    def test_request_and_exception(self):
     178        "A simple exception report can be generated"
     179        try:
     180            request = self.rf.get('/test_view/')
     181            raise ValueError("Can't find my keys")
     182        except ValueError:
     183            exc_type, exc_value, tb = sys.exc_info()
     184        reporter = ExceptionReporter(request, exc_type, exc_value, tb)
     185        text = reporter.get_traceback_text()
     186        self.assertIn('ValueError at /test_view/', text)
     187        self.assertIn("Can't find my keys", text)
     188        self.assertIn('Request Method:', text)
     189        self.assertIn('Request URL:', text)
     190        self.assertIn('Exception Type:', text)
     191        self.assertIn('Exception Value:', text)
     192        self.assertIn('Traceback:', text)
     193        self.assertIn('Request information:', text)
     194        self.assertNotIn('Request data not supplied', text)
     195
     196    def test_no_request(self):
     197        "An exception report can be generated without request"
     198        try:
     199            raise ValueError("Can't find my keys")
     200        except ValueError:
     201            exc_type, exc_value, tb = sys.exc_info()
     202        reporter = ExceptionReporter(None, exc_type, exc_value, tb)
     203        text = reporter.get_traceback_text()
     204        self.assertIn('ValueError', text)
     205        self.assertIn("Can't find my keys", text)
     206        self.assertNotIn('Request Method:', text)
     207        self.assertNotIn('Request URL:', text)
     208        self.assertIn('Exception Type:', text)
     209        self.assertIn('Exception Value:', text)
     210        self.assertIn('Traceback:', text)
     211        self.assertIn('Request data not supplied', text)
     212
     213    def test_no_exception(self):
     214        "An exception report can be generated for just a request"
     215        request = self.rf.get('/test_view/')
     216        reporter = ExceptionReporter(request, None, None, None)
     217        text = reporter.get_traceback_text()
     218
     219    def test_request_and_message(self):
     220        "A message can be provided in addition to a request"
     221        request = self.rf.get('/test_view/')
     222        reporter = ExceptionReporter(request, None, "I'm a little teapot", None)
     223        text = reporter.get_traceback_text()
     224
     225    def test_message_only(self):
     226        reporter = ExceptionReporter(None, None, "I'm a little teapot", None)
     227        text = reporter.get_traceback_text()
     228
     229
    174230class ExceptionReporterFilterTests(TestCase):
    175231    """
    176232    Ensure that sensitive information can be filtered out of error reports.
Back to Top