trio2o/tricircle/common/exceptions.py
Chaoyi Huang ab6bd6cee9 Exception base class refactory
Refactory the exception class to include the failure code,
and parameter format for output, and deal with the exception
during the parameter formatting.

BP: https://blueprints.launchpad.net/tricircle/+spec/implement-stateless

Change-Id: Iec54fc66589199a3dbfc15c4df283466a62e4a10
Signed-off-by: Chaoyi Huang <joehuang@huawei.com>
2016-03-31 10:43:50 +08:00

271 lines
7.6 KiB
Python

# Copyright 2015 Huawei Technologies Co., Ltd.
# 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.
"""
Tricircle base exception handling.
"""
import six
from oslo_log import log as logging
from tricircle.common.i18n import _
from tricircle.common.i18n import _LE
LOG = logging.getLogger(__name__)
class TricircleException(Exception):
"""Base Tricircle 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
headers = {}
safe = False
def __init__(self, message=None, **kwargs):
self.kwargs = kwargs
self.kwargs['message'] = message
if 'code' not in self.kwargs:
self.kwargs['code'] = self.code
for k, v in self.kwargs.items():
if isinstance(v, Exception):
self.kwargs[k] = six.text_type(v)
if self._should_format():
try:
message = self.message % kwargs
except Exception:
# kwargs doesn't match a variable in the message
# log the issue and the kwargs
exc_info = _('Exception class %s in string '
'format operation') % type(self).__name__
for name, value in kwargs.items():
exc_info = exc_info + _(' ; ') + \
name + _(' : ') + six.text_type(value)
exc_info = self.message + _(' ; ') + exc_info
LOG.exception(exc_info)
# no rerasie
# exc_info = sys.exc_info()
# if CONF.fatal_exception_format_errors:
# six.reraise(*exc_info)
# at least get the core message out if something happened
message = self.message
elif isinstance(message, Exception):
message = six.text_type(message)
self.msg = message
super(TricircleException, self).__init__(message)
def _should_format(self):
if self.kwargs['message'] is None and '%(message)' in self.message:
LOG.error(_LE('\%(message)s in message '
'but init parameter is None'))
return self.kwargs['message'] is None or '%(message)' in self.message
def __unicode__(self):
return six.text_type(self.msg)
class BadRequest(TricircleException):
message = _('Bad %(resource)s request: %(msg)s')
class NotFound(TricircleException):
message = _("Resource could not be found.")
code = 404
safe = True
class Conflict(TricircleException):
pass
class NotAuthorized(TricircleException):
message = _("Not authorized.")
class ServiceUnavailable(TricircleException):
message = _("The service is unavailable")
class AdminRequired(NotAuthorized):
message = _("User does not have admin privileges")
class InUse(TricircleException):
message = _("The resource is inuse")
class InvalidConfigurationOption(TricircleException):
message = _("An invalid value was provided for %(opt_name)s: "
"%(opt_value)s")
class EndpointNotAvailable(TricircleException):
message = "Endpoint %(url)s for %(service)s is not available"
def __init__(self, service, url):
super(EndpointNotAvailable, self).__init__(service=service, url=url)
class EndpointNotUnique(TricircleException):
message = "Endpoint for %(service)s in %(pod)s not unique"
def __init__(self, pod, service):
super(EndpointNotUnique, self).__init__(pod=pod, service=service)
class EndpointNotFound(TricircleException):
message = "Endpoint for %(service)s in %(pod)s not found"
def __init__(self, pod, service):
super(EndpointNotFound, self).__init__(pod=pod, service=service)
class ResourceNotFound(TricircleException):
message = "Could not find %(resource_type)s: %(unique_key)s"
def __init__(self, model, unique_key):
resource_type = model.__name__.lower()
super(ResourceNotFound, self).__init__(resource_type=resource_type,
unique_key=unique_key)
class ResourceNotSupported(TricircleException):
message = "%(method)s method not supported for %(resource)s"
def __init__(self, resource, method):
super(ResourceNotSupported, self).__init__(resource=resource,
method=method)
class Invalid(TricircleException):
message = _("Unacceptable parameters.")
code = 400
class InvalidInput(Invalid):
message = _("Invalid input received: %(reason)s")
class InvalidMetadata(Invalid):
message = _("Invalid metadata: %(reason)s")
class InvalidMetadataSize(Invalid):
message = _("Invalid metadata size: %(reason)s")
class MetadataLimitExceeded(TricircleException):
message = _("Maximum number of metadata items exceeds %(allowed)d")
class InvalidReservationExpiration(Invalid):
message = _("Invalid reservation expiration %(expire)s.")
class InvalidQuotaValue(Invalid):
message = _("Change would make usage less than 0 for the following "
"resources: %(unders)s")
class QuotaNotFound(NotFound):
message = _("Quota could not be found")
class QuotaResourceUnknown(QuotaNotFound):
message = _("Unknown quota resources %(unknown)s.")
class ProjectQuotaNotFound(QuotaNotFound):
message = _("Quota for project %(project_id)s could not be found.")
class QuotaClassNotFound(QuotaNotFound):
message = _("Quota class %(class_name)s could not be found.")
class QuotaUsageNotFound(QuotaNotFound):
message = _("Quota usage for project %(project_id)s could not be found.")
class ReservationNotFound(QuotaNotFound):
message = _("Quota reservation %(uuid)s could not be found.")
class OverQuota(TricircleException):
message = _("Quota exceeded for resources: %(overs)s")
class TooManyInstances(TricircleException):
message = _("Quota exceeded for %(overs)s: Requested %(req)s,"
" but already used %(used)s of %(allowed)s %(overs)s")
class OnsetFileLimitExceeded(TricircleException):
message = _("Personality file limit exceeded")
class OnsetFilePathLimitExceeded(OnsetFileLimitExceeded):
message = _("Personality file path too long")
class OnsetFileContentLimitExceeded(OnsetFileLimitExceeded):
message = _("Personality file content too long")
class ExternalNetPodNotSpecify(TricircleException):
message = "Pod for external network not specified"
def __init__(self):
super(ExternalNetPodNotSpecify, self).__init__()
class PodNotFound(NotFound):
message = "Pod %(pod_name)s could not be found."
def __init__(self, pod_name):
super(PodNotFound, self).__init__(pod_name=pod_name)
class ChildQuotaNotZero(TricircleException):
message = _("Child projects having non-zero quota")
# parameter validation error
class ValidationError(TricircleException):
message = _("%(msg)s")
code = 400
# parameter validation error
class HTTPForbiddenError(TricircleException):
message = _("%(msg)s")
code = 403