Files
deb-python-pecan/pecan/middleware/errordocument.py
Ryan Petrello 0f756c60ac Revert "Fix a Py3 compatability issue with WebTest > 1.3.1 < 2.0"
This reverts commit 9ce0a79866.

This was originally an attempted workaround for:
38137ee4b4 (diff-f8658b710075968677d52c7d013ec098R240)
but is an inappropriate fix (that causes a bug of its own).

Change-Id: I3f957a0fff1985596974f51fa154f5de652dc7c5
2014-03-27 16:27:01 -04:00

77 lines
2.5 KiB
Python

import sys
from six import b as b_
from .recursive import ForwardRequestException, RecursionLoop
class StatusPersist(object):
def __init__(self, app, status, url):
self.app = app
self.status = status
self.url = url
def __call__(self, environ, start_response):
def keep_status_start_response(status, headers, exc_info=None):
return start_response(self.status, headers, exc_info)
parts = self.url.split('?')
environ['PATH_INFO'] = parts[0]
if len(parts) > 1:
environ['QUERY_STRING'] = parts[1]
else:
environ['QUERY_STRING'] = ''
try:
return self.app(environ, keep_status_start_response)
except RecursionLoop as e:
environ['wsgi.errors'].write(
'Recursion error getting error page: %s\n' % e
)
keep_status_start_response(
'500 Server Error',
[('Content-type', 'text/plain')],
sys.exc_info()
)
return [b_(
'Error: %s. (Error page could not be fetched)' % self.status
)]
class ErrorDocumentMiddleware(object):
'''
Intersects HTTP response status code, looks it up in the error map defined
in the Pecan app config.py, and routes to the controller assigned to that
status.
'''
def __init__(self, app, error_map):
self.app = app
self.error_map = error_map
def __call__(self, environ, start_response):
def replacement_start_response(status, headers, exc_info=None):
'''
Overrides the default response if the status is defined in the
Pecan app error map configuration.
'''
try:
status_code = int(status.split(' ')[0])
except (ValueError, TypeError): # pragma: nocover
raise Exception((
'ErrorDocumentMiddleware received an invalid '
'status %s' % status
))
if status_code in self.error_map:
def factory(app):
return StatusPersist(
app,
status,
self.error_map[status_code]
)
raise ForwardRequestException(factory=factory)
return start_response(status, headers, exc_info)
app_iter = self.app(environ, replacement_start_response)
return app_iter