web/lib/django/core/handlers/base.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
--- a/web/lib/django/core/handlers/base.py	Wed May 19 17:43:59 2010 +0200
+++ b/web/lib/django/core/handlers/base.py	Tue May 25 02:43:45 2010 +0200
@@ -34,16 +34,16 @@
             try:
                 dot = middleware_path.rindex('.')
             except ValueError:
-                raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
+                raise exceptions.ImproperlyConfigured('%s isn\'t a middleware module' % middleware_path)
             mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
             try:
                 mod = import_module(mw_module)
             except ImportError, e:
-                raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
+                raise exceptions.ImproperlyConfigured('Error importing middleware %s: "%s"' % (mw_module, e))
             try:
                 mw_class = getattr(mod, mw_classname)
             except AttributeError:
-                raise exceptions.ImproperlyConfigured, 'Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname)
+                raise exceptions.ImproperlyConfigured('Middleware module "%s" does not define a "%s" class' % (mw_module, mw_classname))
 
             try:
                 mw_instance = mw_class()
@@ -68,70 +68,82 @@
         from django.core import exceptions, urlresolvers
         from django.conf import settings
 
-        # Apply request middleware
-        for middleware_method in self._request_middleware:
-            response = middleware_method(request)
-            if response:
-                return response
+        try:
+            try:
+                # Setup default url resolver for this thread.
+                urlconf = settings.ROOT_URLCONF
+                urlresolvers.set_urlconf(urlconf)
+                resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
 
-        # Get urlconf from request object, if available.  Otherwise use default.
-        urlconf = getattr(request, "urlconf", settings.ROOT_URLCONF)
-
-        resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
-        try:
-            callback, callback_args, callback_kwargs = resolver.resolve(
-                    request.path_info)
+                # Apply request middleware
+                for middleware_method in self._request_middleware:
+                    response = middleware_method(request)
+                    if response:
+                        return response
 
-            # Apply view middleware
-            for middleware_method in self._view_middleware:
-                response = middleware_method(request, callback, callback_args, callback_kwargs)
-                if response:
-                    return response
+                if hasattr(request, "urlconf"):
+                    # Reset url resolver with a custom urlconf.
+                    urlconf = request.urlconf
+                    urlresolvers.set_urlconf(urlconf)
+                    resolver = urlresolvers.RegexURLResolver(r'^/', urlconf)
 
-            try:
-                response = callback(request, *callback_args, **callback_kwargs)
-            except Exception, e:
-                # If the view raised an exception, run it through exception
-                # middleware, and if the exception middleware returns a
-                # response, use that. Otherwise, reraise the exception.
-                for middleware_method in self._exception_middleware:
-                    response = middleware_method(request, e)
+                callback, callback_args, callback_kwargs = resolver.resolve(
+                        request.path_info)
+
+                # Apply view middleware
+                for middleware_method in self._view_middleware:
+                    response = middleware_method(request, callback, callback_args, callback_kwargs)
                     if response:
                         return response
-                raise
 
-            # Complain if the view returned None (a common error).
-            if response is None:
-                try:
-                    view_name = callback.func_name # If it's a function
-                except AttributeError:
-                    view_name = callback.__class__.__name__ + '.__call__' # If it's a class
-                raise ValueError, "The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name)
-
-            return response
-        except http.Http404, e:
-            if settings.DEBUG:
-                from django.views import debug
-                return debug.technical_404_response(request, e)
-            else:
                 try:
-                    callback, param_dict = resolver.resolve404()
-                    return callback(request, **param_dict)
-                except:
+                    response = callback(request, *callback_args, **callback_kwargs)
+                except Exception, e:
+                    # If the view raised an exception, run it through exception
+                    # middleware, and if the exception middleware returns a
+                    # response, use that. Otherwise, reraise the exception.
+                    for middleware_method in self._exception_middleware:
+                        response = middleware_method(request, e)
+                        if response:
+                            return response
+                    raise
+
+                # Complain if the view returned None (a common error).
+                if response is None:
                     try:
-                        return self.handle_uncaught_exception(request, resolver, sys.exc_info())
-                    finally:
-                        receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
-        except exceptions.PermissionDenied:
-            return http.HttpResponseForbidden('<h1>Permission denied</h1>')
-        except SystemExit:
-            # Allow sys.exit() to actually exit. See tickets #1023 and #4701
-            raise
-        except: # Handle everything else, including SuspiciousOperation, etc.
-            # Get the exception info now, in case another exception is thrown later.
-            exc_info = sys.exc_info()
-            receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
-            return self.handle_uncaught_exception(request, resolver, exc_info)
+                        view_name = callback.func_name # If it's a function
+                    except AttributeError:
+                        view_name = callback.__class__.__name__ + '.__call__' # If it's a class
+                    raise ValueError("The view %s.%s didn't return an HttpResponse object." % (callback.__module__, view_name))
+
+                return response
+            except http.Http404, e:
+                if settings.DEBUG:
+                    from django.views import debug
+                    return debug.technical_404_response(request, e)
+                else:
+                    try:
+                        callback, param_dict = resolver.resolve404()
+                        return callback(request, **param_dict)
+                    except:
+                        try:
+                            return self.handle_uncaught_exception(request, resolver, sys.exc_info())
+                        finally:
+                            receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
+            except exceptions.PermissionDenied:
+                return http.HttpResponseForbidden('<h1>Permission denied</h1>')
+            except SystemExit:
+                # Allow sys.exit() to actually exit. See tickets #1023 and #4701
+                raise
+            except: # Handle everything else, including SuspiciousOperation, etc.
+                # Get the exception info now, in case another exception is thrown later.
+                exc_info = sys.exc_info()
+                receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
+                return self.handle_uncaught_exception(request, resolver, exc_info)
+        finally:
+            # Reset URLconf for this thread on the way out for complete
+            # isolation of request.urlconf
+            urlresolvers.set_urlconf(None)
 
     def handle_uncaught_exception(self, request, resolver, exc_info):
         """
@@ -161,6 +173,9 @@
             request_repr = "Request repr() unavailable"
         message = "%s\n\n%s" % (self._get_traceback(exc_info), request_repr)
         mail_admins(subject, message, fail_silently=True)
+        # If Http500 handler is not installed, re-raise last exception
+        if resolver.urlconf_module is None:
+            raise exc_info[1], None, exc_info[2]
         # Return an HttpResponse that displays a friendly error message.
         callback, param_dict = resolver.resolve500()
         return callback(request, **param_dict)