From 29f5c1a101802e0ba66d72195fbe4e9d340a96a0 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Thu, 10 Dec 2009 15:54:43 +0000 Subject: - Added a "Special Exceptions" section to the "Views" narrative documentation chapter explaining the effect of raising ``repoze.bfg.exceptions.NotFound`` and ``repoze.bfg.exceptions.Forbidden`` from within view code. - When the ``repoze.bfg.exceptions.NotFound`` or ``repoze.bfg.exceptions.Forbidden`` error is raised from within a custom root factory or the ``factory`` of a route, the appropriate response is now sent to the requesting user agent (the result of the notfound view or the forbidden view, respectively). When these errors are raised from within a root factory, the ``context`` passed to the notfound or forbidden view will be ``None``. Also, the request will not be decorated with ``view_name``, ``subpath``, ``context``, etc. as would normally be the case if traversal had been allowed to take place. --- repoze/bfg/router.py | 116 ++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 57 deletions(-) (limited to 'repoze/bfg/router.py') diff --git a/repoze/bfg/router.py b/repoze/bfg/router.py index deffa4e17..630aa201c 100644 --- a/repoze/bfg/router.py +++ b/repoze/bfg/router.py @@ -65,71 +65,73 @@ class Router(object): try: # setup request = Request(environ) + context = None threadlocals['request'] = request attrs = request.__dict__ attrs['registry'] = registry has_listeners and registry.notify(NewRequest(request)) + + try: + # root resolution + root_factory = self.root_factory + if self.routes_mapper is not None: + info = self.routes_mapper(request) + match, route = info['match'], info['route'] + if route is not None: + environ['wsgiorg.routing_args'] = ((), match) + environ['bfg.routes.route'] = route + environ['bfg.routes.matchdict'] = match + request.matchdict = match + iface = registry.queryUtility(IRouteRequest, + name=route.name) + if iface is not None: + alsoProvides(request, iface) + root_factory = route.factory or self.root_factory + + root = root_factory(request) + attrs['root'] = root + + # view lookup + traverser = registry.adapters.queryAdapter(root, ITraverser) + if traverser is None: + traverser = ModelGraphTraverser(root) + tdict = traverser(request) + context, view_name, subpath, traversed, vroot, vroot_path = ( + tdict['context'], tdict['view_name'], tdict['subpath'], + tdict['traversed'], tdict['virtual_root'], + tdict['virtual_root_path']) + attrs.update(tdict) + has_listeners and registry.notify(AfterTraversal(request)) + provides = map(providedBy, (context, request)) + view_callable = registry.adapters.lookup( + provides, IView, name=view_name, default=None) - # root resolution - root_factory = self.root_factory - if self.routes_mapper is not None: - info = self.routes_mapper(request) - match, route = info['match'], info['route'] - if route is not None: - environ['wsgiorg.routing_args'] = ((), match) - environ['bfg.routes.route'] = route - environ['bfg.routes.matchdict'] = match - request.matchdict = match - iface = registry.queryUtility(IRouteRequest, - name=route.name) - if iface is not None: - alsoProvides(request, iface) - root_factory = route.factory or self.root_factory - - root = root_factory(request) - attrs['root'] = root - - # view lookup - traverser = registry.adapters.queryAdapter(root, ITraverser) - if traverser is None: - traverser = ModelGraphTraverser(root) - tdict = traverser(request) - context, view_name, subpath, traversed, vroot, vroot_path = ( - tdict['context'], tdict['view_name'], tdict['subpath'], - tdict['traversed'], tdict['virtual_root'], - tdict['virtual_root_path']) - attrs.update(tdict) - has_listeners and registry.notify(AfterTraversal(request)) - provides = map(providedBy, (context, request)) - view_callable = registry.adapters.lookup( - provides, IView, name=view_name, default=None) - - # view execution - if view_callable is None: - if self.debug_notfound: - msg = ( - 'debug_notfound of url %s; path_info: %r, context: %r, ' - 'view_name: %r, subpath: %r, traversed: %r, ' - 'root: %r, vroot: %r, vroot_path: %r' % ( - request.url, request.path_info, context, view_name, - subpath, traversed, root, vroot, vroot_path) - ) - logger and logger.debug(msg) + # view execution + if view_callable is None: + if self.debug_notfound: + msg = ( + 'debug_notfound of url %s; path_info: %r, context: %r, ' + 'view_name: %r, subpath: %r, traversed: %r, ' + 'root: %r, vroot: %r, vroot_path: %r' % ( + request.url, request.path_info, context, view_name, + subpath, traversed, root, vroot, vroot_path) + ) + logger and logger.debug(msg) + else: + msg = request.path_info + environ['repoze.bfg.message'] = msg + response = self.notfound_view(context, request) else: - msg = request.path_info + response = view_callable(context, request) + + except Forbidden, why: + msg = why[0] + environ['repoze.bfg.message'] = msg + response = self.forbidden_view(context, request) + except NotFound, why: + msg = why[0] environ['repoze.bfg.message'] = msg response = self.notfound_view(context, request) - else: - try: - response = view_callable(context, request) - except Forbidden, why: - msg = why[0] - environ['repoze.bfg.message'] = msg - response = self.forbidden_view(context, request) - except NotFound, why: - msg = why[0] - environ['repoze.bfg.message'] = msg - response = self.notfound_view(context, request) # response handling has_listeners and registry.notify(NewResponse(response)) -- cgit v1.2.3