74 lines
2.7 KiB
Python
74 lines
2.7 KiB
Python
# Copyright 2010 United States Government as represented by the
|
|
# Administrator of the National Aeronautics and Space Administration.
|
|
# All Rights Reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
from oslo_log import log
|
|
import six
|
|
import webob.dec
|
|
import webob.exc
|
|
|
|
from manila.api.openstack import wsgi
|
|
from manila import utils
|
|
from manila.wsgi import common as base_wsgi
|
|
|
|
LOG = log.getLogger(__name__)
|
|
|
|
|
|
class FaultWrapper(base_wsgi.Middleware):
|
|
"""Calls down the middleware stack, making exceptions into faults."""
|
|
|
|
_status_to_type = {}
|
|
|
|
@staticmethod
|
|
def status_to_type(status):
|
|
if not FaultWrapper._status_to_type:
|
|
for clazz in utils.walk_class_hierarchy(webob.exc.HTTPError):
|
|
FaultWrapper._status_to_type[clazz.code] = clazz
|
|
return FaultWrapper._status_to_type.get(
|
|
status, webob.exc.HTTPInternalServerError)()
|
|
|
|
def _error(self, inner, req):
|
|
LOG.exception("Caught error: %s", inner)
|
|
|
|
safe = getattr(inner, 'safe', False)
|
|
headers = getattr(inner, 'headers', None)
|
|
status = getattr(inner, 'code', 500)
|
|
if status is None:
|
|
status = 500
|
|
|
|
msg_dict = dict(url=req.url, status=status)
|
|
LOG.info("%(url)s returned with HTTP %(status)d", msg_dict)
|
|
outer = self.status_to_type(status)
|
|
if headers:
|
|
outer.headers = headers
|
|
# NOTE(johannes): We leave the explanation empty here on
|
|
# purpose. It could possibly have sensitive information
|
|
# that should not be returned back to the user. See
|
|
# bugs 868360 and 874472
|
|
# NOTE(eglynn): However, it would be over-conservative and
|
|
# inconsistent with the EC2 API to hide every exception,
|
|
# including those that are safe to expose, see bug 1021373
|
|
if safe:
|
|
outer.explanation = '%s: %s' % (inner.__class__.__name__,
|
|
six.text_type(inner))
|
|
return wsgi.Fault(outer)
|
|
|
|
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
|
def __call__(self, req):
|
|
try:
|
|
return req.get_response(self.application)
|
|
except Exception as ex:
|
|
return self._error(ex, req)
|