# Copyright 2017 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. """Cyborg base exception handling. SHOULD include dedicated exception logging. """ from oslo_log import log import six from six.moves import http_client from cyborg.common.i18n import _ from cyborg.conf import CONF LOG = log.getLogger(__name__) class CyborgException(Exception): """Base Cyborg Exception To correctly use this class, inherit from it and define a '_msg_fmt' property. That message will get printf'd with the keyword arguments provided to the constructor. If you need to access the message from an exception you should use six.text_type(exc) """ _msg_fmt = _("An unknown exception occurred.") code = http_client.INTERNAL_SERVER_ERROR headers = {} safe = False 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 not message: try: message = self._msg_fmt % kwargs except Exception: # kwargs doesn't match a variable in self._msg_fmt # log the issue and the kwargs LOG.exception('Exception in string format operation') for name, value in kwargs.items(): LOG.error("%s: %s" % (name, value)) if CONF.fatal_exception_format_errors: raise else: # at least get the core self._msg_fmt out if something # happened message = self._msg_fmt super(CyborgException, self).__init__(message) def __str__(self): """Encode to utf-8 then wsme api can consume it as well.""" if not six.PY3: return unicode(self.args[0]).encode('utf-8') return self.args[0] def __unicode__(self): """Return a unicode representation of the exception message.""" return unicode(self.args[0]) class ConfigInvalid(CyborgException): _msg_fmt = _("Invalid configuration file. %(error_msg)s") class AcceleratorAlreadyExists(CyborgException): _msg_fmt = _("Accelerator with uuid %(uuid)s already exists.") class Invalid(CyborgException): _msg_fmt = _("Invalid parameters.") code = http_client.BAD_REQUEST class InvalidIdentity(Invalid): _msg_fmt = _("Expected a uuid/id but received %(identity)s.") class InvalidUUID(Invalid): _msg_fmt = _("Expected a uuid but received %(uuid)s.") class InvalidJsonType(Invalid): _msg_fmt = _("%(value)s is not JSON serializable.") class NotAuthorized(CyborgException): _msg_fmt = _("Not authorized.") code = http_client.FORBIDDEN class HTTPForbidden(NotAuthorized): _msg_fmt = _("Access was denied to the following resource: %(resource)s")