diff options
author | Jonathan LaCour <jonathan@cleverdevil.org> | 2013-04-12 11:56:56 -0700 |
---|---|---|
committer | Jonathan LaCour <jonathan@cleverdevil.org> | 2013-04-12 11:56:56 -0700 |
commit | 0f94eea7a301ae5493097145700aba98f932fa3e (patch) | |
tree | 4f84e4ee1ac1fb1c42d4a14152a5a1b0cc330ab6 | |
parent | c3339f27552f38f16ad74e0f9da2da198cb8585a (diff) | |
parent | b5d69b5624f3e359c3c0c898e2b2dd23f85af01b (diff) | |
download | pecan-0f94eea7a301ae5493097145700aba98f932fa3e.tar.gz |
Merge pull request #206 from ryanpetrello/next
Store exceptions raised by ``abort`` in the WSGI environ.
-rw-r--r-- | docs/source/routing.rst | 7 | ||||
-rw-r--r-- | pecan/core.py | 1 | ||||
-rw-r--r-- | pecan/tests/middleware/test_errordocument.py | 36 |
3 files changed, 44 insertions, 0 deletions
diff --git a/docs/source/routing.rst b/docs/source/routing.rst index e27baf6..6ed3524 100644 --- a/docs/source/routing.rst +++ b/docs/source/routing.rst @@ -163,6 +163,13 @@ Pecan also comes with ``abort``, a utility function for raising HTTP errors: abort(404) +Under the hood, ``abort`` raises an instance of +``webob.exc.WSGIHTTPException`` which is used by pecan to render default +response bodies for HTTP errors. This exception is stored in the WSGI request +environ at ``pecan.original_exception``, where it can be accessed later in the +request cycle (by, for example, other middleware or :ref:`errors`). + + Routing to Subcontrollers with ``_lookup`` ------------------------------------------ diff --git a/pecan/core.py b/pecan/core.py index 5897988..e4fdd99 100644 --- a/pecan/core.py +++ b/pecan/core.py @@ -545,6 +545,7 @@ class Pecan(object): # if this is an HTTP Exception, set it as the response if isinstance(e, exc.HTTPException): state.response = e + environ['pecan.original_exception'] = e # if this is not an internal redirect, run error hooks if not isinstance(e, ForwardRequestException): diff --git a/pecan/tests/middleware/test_errordocument.py b/pecan/tests/middleware/test_errordocument.py index 92c4c08..c4faa42 100644 --- a/pecan/tests/middleware/test_errordocument.py +++ b/pecan/tests/middleware/test_errordocument.py @@ -1,5 +1,8 @@ +import json + from webtest import TestApp +import pecan from pecan.middleware.errordocument import ErrorDocumentMiddleware from pecan.middleware.recursive import RecursiveMiddleware from pecan.tests import PecanTestCase @@ -52,3 +55,36 @@ class TestErrorDocumentMiddleware(PecanTestCase): assert r.status_int == 404 assert r.body == ('Error: 404 Not Found. ' '(Error page could not be fetched)') + + def test_original_exception(self): + + class RootController(object): + + @pecan.expose() + def index(self): + if pecan.request.method != 'POST': + pecan.abort(405, 'You have to POST, dummy!') + return 'Hello, World!' + + @pecan.expose('json') + def error(self, status): + return dict( + status=int(status), + reason=pecan.request.environ[ + 'pecan.original_exception' + ].detail + ) + + app = pecan.Pecan(RootController()) + app = RecursiveMiddleware(ErrorDocumentMiddleware(app, { + 405: '/error/405' + })) + app = TestApp(app) + + assert app.post('/').status_int == 200 + r = app.get('/', expect_errors=405) + assert r.status_int == 405 + + resp = json.loads(r.body) + assert resp['status'] == 405 + assert resp['reason'] == 'You have to POST, dummy!' |