Django

Code

Changeset 414

Show
Ignore:
Timestamp:
08/05/05 17:22:41 (3 years ago)
Author:
adrian
Message:

Greatly improved the 404 error message when DEBUG=True. If none of the urlpatterns matches, Django now displays a list of all the urlpatterns it tried. This should catch a lot of newbie errors, and it's helpful even for power users.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/core/handlers/base.py

    r411 r414  
    6161                    return response 
    6262            return callback(request, **param_dict) 
    63         except exceptions.Http404
     63        except exceptions.Http404, e
    6464            if DEBUG: 
    65                 return self.get_technical_error_response(is404=True
     65                return self.get_technical_error_response(is404=True, exception=e
    6666            else: 
    6767                callback, param_dict = resolver.resolve404() 
     
    100100        return callback(request, **param_dict) 
    101101 
    102     def get_technical_error_response(self, is404=False): 
     102    def get_technical_error_response(self, is404=False, exception=None): 
    103103        """ 
    104104        Returns an HttpResponse that displays a TECHNICAL error message for a 
    105105        fundamental database or coding error. 
    106106        """ 
    107         error_string = "There's been an error:\n\n%s" % self._get_traceback() 
    108         responseClass = is404 and httpwrappers.HttpResponseNotFound or httpwrappers.HttpResponseServerError 
    109         return responseClass(error_string, mimetype='text/plain') 
     107        if is404: 
     108            from django.conf.settings import ROOT_URLCONF 
     109            from django.utils.html import escape 
     110            html = ['<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'] 
     111            html.append('<html><head><title>Error 404</title>') 
     112            # Explicitly tell robots not to archive this, in case this slips 
     113            # onto a production site. 
     114            html.append('<meta name="robots" content="NONE,NOARCHIVE" />') 
     115            html.append('</head><body><h1>Error 404</h1>') 
     116            try: 
     117                tried = exception.args[0]['tried'] 
     118            except (IndexError, TypeError): 
     119                if exception.args: 
     120                    html.append('<p>%s</p>' % escape(exception.args[0])) 
     121            else: 
     122                html.append('<p>Using the URLconf defined in <code>%s</code>, Django tried these URL patterns, in this order:</p>' % ROOT_URLCONF) 
     123                html.append('<ul>%s</ul>' % ''.join(['<li><code>%s</code></li>' % escape(t).replace(' ', '&nbsp;') for t in tried])) 
     124                html.append("<p>The current URL, <code><strong>%r</strong></code>, didn't match any of these.</p>" % exception.args[0]['path']) 
     125            html.append("<hr /><p>You're seeing this error because you have <code>DEBUG = True</code> in your Django settings file. Change that to <code>False</code>, and Django will display a standard 404 page.</p>") 
     126            html.append('</body></html>') 
     127            return httpwrappers.HttpResponseNotFound('\n'.join(html)) 
     128        else: 
     129            output = "There's been an error:\n\n%s" % self._get_traceback() 
     130            return httpwrappers.HttpResponseServerError(output, mimetype='text/plain') 
    110131 
    111132    def _get_traceback(self): 
  • django/trunk/django/core/urlresolvers.py

    r411 r414  
    1010from django.core.exceptions import Http404, ViewDoesNotExist 
    1111import re 
     12 
     13class Resolver404(Http404): 
     14    pass 
    1215 
    1316def get_mod_func(callback): 
     
    5356 
    5457    def resolve(self, path): 
     58        tried = [] 
    5559        match = self.regex.search(path) 
    5660        if match: 
    5761            new_path = path[match.end():] 
    5862            for pattern in self.url_patterns: 
    59                 sub_match = pattern.resolve(new_path) 
    60                 if sub_match: 
    61                     return sub_match 
    62             # None of the regexes matched, so raise a 404. 
    63             raise Http404, "Tried all URL patterns but didn't find a match for %r" % path 
     63                try: 
     64                    sub_match = pattern.resolve(new_path) 
     65                except Resolver404, e: 
     66                    tried.extend([(pattern.regex.pattern + '   ' + t) for t in e.args[0]['tried']]) 
     67                else: 
     68                    if sub_match: 
     69                        return sub_match 
     70                    tried.append(pattern.regex.pattern) 
     71            raise Resolver404, {'tried': tried, 'path': new_path} 
    6472 
    6573    def _get_urlconf_module(self):