Michael Merickel
2017-05-23 07e0e15fdafb28843a92cd03681a07aa652008a9
allow the execution policy to perform a last-ditch effort to render an exception view
2 files modified
41 ■■■■■ changed files
pyramid/router.py 14 ●●●● patch | view | raw | blame | history
pyramid/tests/test_router.py 27 ●●●●● patch | view | raw | blame | history
pyramid/router.py
@@ -1,3 +1,4 @@
import sys
from zope.interface import (
    implementer,
    providedBy,
@@ -24,6 +25,7 @@
    BeforeTraversal,
    )
from pyramid.compat import reraise
from pyramid.httpexceptions import HTTPNotFound
from pyramid.request import Request
from pyramid.view import _call_view
@@ -252,7 +254,15 @@
        response = self.execution_policy(environ, self)
        return response(environ, start_response)
def default_execution_policy(environ, router):
    request = router.make_request(environ)
    return router.invoke_request(request)
    try:
        return router.invoke_request(request)
    except Exception:
        exc_info = sys.exc_info()
        try:
            return request.invoke_exception_view(exc_info)
        except HTTPNotFound:
            reraise(*exc_info)
        finally:
            del exc_info  # avoid local ref cycle
pyramid/tests/test_router.py
@@ -1284,6 +1284,33 @@
        self.assertEqual(resp.status_code, 200)
        self.assertEqual(resp.body, b'foo')
    def test_execution_policy_handles_exception(self):
        from pyramid.interfaces import IViewClassifier
        from pyramid.interfaces import IExceptionViewClassifier
        from pyramid.interfaces import IRequest
        class Exception1(Exception):
            pass
        class Exception2(Exception):
            pass
        req_iface = self._registerRouteRequest('foo')
        self._connectRoute('foo', 'archives/:action/:article', None)
        view = DummyView(DummyResponse(), raise_exception=Exception1)
        self._registerView(view, '', IViewClassifier, req_iface, None)
        exception_view1 = DummyView(DummyResponse(),
                                    raise_exception=Exception2)
        self._registerView(exception_view1, '', IExceptionViewClassifier,
                           IRequest, Exception1)
        response = DummyResponse()
        response.app_iter = ["Hello, world"]
        exception_view2 = DummyView(response)
        self._registerView(exception_view2, '', IExceptionViewClassifier,
                           IRequest, Exception2)
        environ = self._makeEnviron(PATH_INFO='/archives/action1/article1')
        start_response = DummyStartResponse()
        router = self._makeOne()
        result = router(environ, start_response)
        self.assertEqual(result, ["Hello, world"])
class DummyPredicate(object):
    def __call__(self, info, request):
        return True