mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	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.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@414 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -60,9 +60,9 @@ class BaseHandler: | ||||
|                 if response: | ||||
|                     return response | ||||
|             return callback(request, **param_dict) | ||||
|         except exceptions.Http404: | ||||
|         except exceptions.Http404, e: | ||||
|             if DEBUG: | ||||
|                 return self.get_technical_error_response(is404=True) | ||||
|                 return self.get_technical_error_response(is404=True, exception=e) | ||||
|             else: | ||||
|                 callback, param_dict = resolver.resolve404() | ||||
|                 return callback(request, **param_dict) | ||||
| @@ -99,14 +99,35 @@ class BaseHandler: | ||||
|         callback, param_dict = resolver.resolve500() | ||||
|         return callback(request, **param_dict) | ||||
|  | ||||
|     def get_technical_error_response(self, is404=False): | ||||
|     def get_technical_error_response(self, is404=False, exception=None): | ||||
|         """ | ||||
|         Returns an HttpResponse that displays a TECHNICAL error message for a | ||||
|         fundamental database or coding error. | ||||
|         """ | ||||
|         error_string = "There's been an error:\n\n%s" % self._get_traceback() | ||||
|         responseClass = is404 and httpwrappers.HttpResponseNotFound or httpwrappers.HttpResponseServerError | ||||
|         return responseClass(error_string, mimetype='text/plain') | ||||
|         if is404: | ||||
|             from django.conf.settings import ROOT_URLCONF | ||||
|             from django.utils.html import escape | ||||
|             html = ['<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'] | ||||
|             html.append('<html><head><title>Error 404</title>') | ||||
|             # Explicitly tell robots not to archive this, in case this slips | ||||
|             # onto a production site. | ||||
|             html.append('<meta name="robots" content="NONE,NOARCHIVE" />') | ||||
|             html.append('</head><body><h1>Error 404</h1>') | ||||
|             try: | ||||
|                 tried = exception.args[0]['tried'] | ||||
|             except (IndexError, TypeError): | ||||
|                 if exception.args: | ||||
|                     html.append('<p>%s</p>' % escape(exception.args[0])) | ||||
|             else: | ||||
|                 html.append('<p>Using the URLconf defined in <code>%s</code>, Django tried these URL patterns, in this order:</p>' % ROOT_URLCONF) | ||||
|                 html.append('<ul>%s</ul>' % ''.join(['<li><code>%s</code></li>' % escape(t).replace(' ', ' ') for t in tried])) | ||||
|                 html.append("<p>The current URL, <code><strong>%r</strong></code>, didn't match any of these.</p>" % exception.args[0]['path']) | ||||
|             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>") | ||||
|             html.append('</body></html>') | ||||
|             return httpwrappers.HttpResponseNotFound('\n'.join(html)) | ||||
|         else: | ||||
|             output = "There's been an error:\n\n%s" % self._get_traceback() | ||||
|             return httpwrappers.HttpResponseServerError(output, mimetype='text/plain') | ||||
|  | ||||
|     def _get_traceback(self): | ||||
|         "Helper function to return the traceback as a string" | ||||
|   | ||||
| @@ -10,6 +10,9 @@ a string) and returns a tuple in this format: | ||||
| from django.core.exceptions import Http404, ViewDoesNotExist | ||||
| import re | ||||
|  | ||||
| class Resolver404(Http404): | ||||
|     pass | ||||
|  | ||||
| def get_mod_func(callback): | ||||
|     # Converts 'django.views.news.stories.story_detail' to | ||||
|     # ['django.views.news.stories', 'story_detail'] | ||||
| @@ -52,15 +55,20 @@ class RegexURLResolver: | ||||
|         self.urlconf_name = urlconf_name | ||||
|  | ||||
|     def resolve(self, path): | ||||
|         tried = [] | ||||
|         match = self.regex.search(path) | ||||
|         if match: | ||||
|             new_path = path[match.end():] | ||||
|             for pattern in self.url_patterns: | ||||
|                 sub_match = pattern.resolve(new_path) | ||||
|                 if sub_match: | ||||
|                     return sub_match | ||||
|             # None of the regexes matched, so raise a 404. | ||||
|             raise Http404, "Tried all URL patterns but didn't find a match for %r" % path | ||||
|                 try: | ||||
|                     sub_match = pattern.resolve(new_path) | ||||
|                 except Resolver404, e: | ||||
|                     tried.extend([(pattern.regex.pattern + '   ' + t) for t in e.args[0]['tried']]) | ||||
|                 else: | ||||
|                     if sub_match: | ||||
|                         return sub_match | ||||
|                     tried.append(pattern.regex.pattern) | ||||
|             raise Resolver404, {'tried': tried, 'path': new_path} | ||||
|  | ||||
|     def _get_urlconf_module(self): | ||||
|         self.urlconf_module = __import__(self.urlconf_name, '', '', ['']) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user