gluon/gluon/common/exception.py

184 lines
5.3 KiB
Python

# Copyright 2015, Ericsson AB
#
# 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.
"""Gluon base exception handling.
Includes decorator for re-raising Cloudpulse-type exceptions.
"""
import six
from oslo_config import cfg
from oslo_log import log as logging
from oslo_log._i18n import _
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
class GluonException(Exception):
"""Base Gluon Exception
To correctly use this class, inherit from it and define
a 'message' property. That message will get printf'd
with the keyword arguments provided to the constructor.
"""
message = _("An unknown exception occurred.")
code = 500
def __init__(self, message=None, **kwargs):
self.kwargs = kwargs
if 'code' not in self.kwargs:
try:
self.kwargs['code'] = self.code
except AttributeError:
pass
if message:
self.message = message
try:
self.message = self.message % kwargs
except Exception as e:
# kwargs doesn't match a variable in the message
# log the issue and the kwargs
LOG.exception('Exception in string format operation')
for name, value in six.iteritems(kwargs):
LOG.error("%(name)s: %(value)s" %
{'name': name, 'value': value})
try:
if CONF.fatal_exception_format_errors:
raise e
except cfg.NoSuchOptError:
# Note: work around for Bug: #1447873
if CONF.oslo_versionedobjects.fatal_exception_format_errors:
raise e
super(GluonException, self).__init__(self.message)
def __str__(self):
if six.PY3:
return self.message
return self.message.encode('utf-8')
def __unicode__(self):
return self.message
def format_message(self):
if self.__class__.__name__.endswith('_Remote'):
return self.args[0]
else:
return six.text_type(self)
class Conflict(GluonException):
message = _('Conflict.')
code = 409
class AlreadyExists(Conflict):
message = _("Object of %(cls)s with %(key)s \"%(value)s\" already exists.")
class NotFound(GluonException):
code = 404
message = _("Object of %(cls)s with Primay Key %(key)s not found.")
class BackendDoesNotExsist(GluonException):
code = 409
message = _("Backend with name %(name)s does not exsist.")
class GluonClientException(GluonException):
"""Base exception which exceptions from Gluon are mapped into.
NOTE: on the client side, we use different exception types in order
to allow client library users to handle server exceptions in try...except
blocks. The actual error message is the one generated on the server side.
"""
status_code = 0
def __init__(self, message=None, **kwargs):
if 'status_code' in kwargs:
self.status_code = kwargs['status_code']
super(GluonClientException, self).__init__(message, **kwargs)
class EndpointNotFound(GluonClientException):
message = _("Could not find Service or Region in Service Catalog.")
class EndpointTypeNotFound(GluonClientException):
message = _("Could not find endpoint type %(type_)s in Service Catalog.")
class AmbiguousEndpoints(GluonClientException):
message = _("Found more than one matching endpoint in Service Catalog: "
"%(matching_endpoints)")
class RequestURITooLong(GluonClientException):
"""Raised when a request fails with HTTP error 414."""
def __init__(self, **kwargs):
self.excess = kwargs.get('excess', 0)
super(RequestURITooLong, self).__init__(**kwargs)
class ConnectionFailed(GluonClientException):
message = _("Connection to Gluon failed: %(reason)s")
class SslCertificateValidationError(GluonClientException):
message = _("SSL certificate validation has failed: %(reason)s")
class MalformedResponseBody(GluonClientException):
message = _("Malformed response body: %(reason)s")
class InvalidContentType(GluonClientException):
message = _("Invalid content type %(content_type)s.")
class InvalidConfigurationOption(GluonClientException):
"""An error due to an invalid configuration option value."""
message = _("An invalid value for configuration option %(opt_name): "
"%(opt_value)")
class PolicyInitError(GluonClientException):
"""An error due to policy initialization failure."""
message = _("Failed to initialize policy %(policy)s because %(reason)s.")
class PolicyCheckError(GluonClientException):
"""An error due to a policy check failure."""
message = _("Failed to check policy %(policy)s because %(reason)s.")
class InvalidFileFormat(GluonClientException):
"""An error due to a invalid API specification file."""
message = _("Invalid file format")