Store exceptions raised by `abort` in the WSGI environ.
This makes it easier to access the original exception later in the request cycle (e.g., other middleware or in custom error handlers).
This commit is contained in:
@@ -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``
|
||||
------------------------------------------
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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!'
|
||||
|
||||
Reference in New Issue
Block a user