This makes it easier to access the original exception later in the request cycle (e.g., other middleware or in custom error handlers).
91 lines
2.9 KiB
Python
91 lines
2.9 KiB
Python
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
|
|
|
|
|
|
def four_oh_four_app(environ, start_response):
|
|
if environ['PATH_INFO'].startswith('/error'):
|
|
code = environ['PATH_INFO'].split('/')[2]
|
|
start_response("200 OK", [('Content-type', 'text/plain')])
|
|
|
|
body = "Error: %s" % code
|
|
if environ['QUERY_STRING']:
|
|
body += "\nQS: %s" % environ['QUERY_STRING']
|
|
return [body]
|
|
start_response("404 Not Found", [('Content-type', 'text/plain')])
|
|
return []
|
|
|
|
|
|
class TestErrorDocumentMiddleware(PecanTestCase):
|
|
|
|
def setUp(self):
|
|
super(TestErrorDocumentMiddleware, self).setUp()
|
|
self.app = TestApp(RecursiveMiddleware(ErrorDocumentMiddleware(
|
|
four_oh_four_app, {404: '/error/404'}
|
|
)))
|
|
|
|
def test_hit_error_page(self):
|
|
r = self.app.get('/error/404')
|
|
assert r.status_int == 200
|
|
assert r.body == 'Error: 404'
|
|
|
|
def test_middleware_routes_to_404_message(self):
|
|
r = self.app.get('/', expect_errors=True)
|
|
assert r.status_int == 404
|
|
assert r.body == 'Error: 404'
|
|
|
|
def test_error_endpoint_with_query_string(self):
|
|
app = TestApp(RecursiveMiddleware(ErrorDocumentMiddleware(
|
|
four_oh_four_app, {404: '/error/404?foo=bar'}
|
|
)))
|
|
r = app.get('/', expect_errors=True)
|
|
assert r.status_int == 404
|
|
assert r.body == 'Error: 404\nQS: foo=bar'
|
|
|
|
def test_error_with_recursion_loop(self):
|
|
app = TestApp(RecursiveMiddleware(ErrorDocumentMiddleware(
|
|
four_oh_four_app, {404: '/'}
|
|
)))
|
|
r = app.get('/', expect_errors=True)
|
|
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!'
|