Avoid serializing CinderExceptions before they are translated
CinderExceptions were being unicode()'d when being wrapped in an HTTPException, and this was causing the delayed translation to fail for those errors. Also, CinderExceptions have a 'message' class attribute that holds the generic error message template, e.g. "Backup %(backup_id)s is not found", unfortunately, because the names are the same, it was overshadowing the actual exception instance 'message', e.g. "Backup 1 is not found", when translating. This patch puts the exception's actual message in a new field called 'msg'. Fixes Bug: #1214102 Change-Id: Ied9abcc3d05454852c0a5891432eb181220a744e
This commit is contained in:
@@ -131,7 +131,7 @@ class BackupsController(wsgi.Controller):
|
||||
try:
|
||||
backup = self.backup_api.get(context, backup_id=id)
|
||||
except exception.BackupNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
|
||||
return self._view_builder.detail(req, backup)
|
||||
|
||||
@@ -145,9 +145,9 @@ class BackupsController(wsgi.Controller):
|
||||
try:
|
||||
self.backup_api.delete(context, id)
|
||||
except exception.BackupNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
except exception.InvalidBackup as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
@@ -207,11 +207,11 @@ class BackupsController(wsgi.Controller):
|
||||
new_backup = self.backup_api.create(context, name, description,
|
||||
volume_id, container)
|
||||
except exception.InvalidVolume as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
except exception.VolumeNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
except exception.ServiceNotFound as error:
|
||||
raise exc.HTTPInternalServerError(explanation=unicode(error))
|
||||
raise exc.HTTPInternalServerError(explanation=error.msg)
|
||||
|
||||
retval = self._view_builder.summary(req, dict(new_backup.iteritems()))
|
||||
return retval
|
||||
@@ -244,21 +244,21 @@ class BackupsController(wsgi.Controller):
|
||||
backup_id=id,
|
||||
volume_id=volume_id)
|
||||
except exception.InvalidInput as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
except exception.InvalidVolume as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
except exception.InvalidBackup as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
except exception.BackupNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
except exception.VolumeNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
except exception.VolumeSizeExceedsAvailableQuota as error:
|
||||
raise exc.HTTPRequestEntityTooLarge(
|
||||
explanation=error.message, headers={'Retry-After': 0})
|
||||
explanation=error.msg, headers={'Retry-After': 0})
|
||||
except exception.VolumeLimitExceeded as error:
|
||||
raise exc.HTTPRequestEntityTooLarge(
|
||||
explanation=error.message, headers={'Retry-After': 0})
|
||||
explanation=error.msg, headers={'Retry-After': 0})
|
||||
|
||||
retval = self._view_builder.restore_summary(
|
||||
req, dict(new_restore.iteritems()))
|
||||
|
||||
@@ -64,7 +64,7 @@ class VolumeTypeExtraSpecsController(wsgi.Controller):
|
||||
try:
|
||||
volume_types.get_volume_type(context, type_id)
|
||||
except exception.NotFound as ex:
|
||||
raise webob.exc.HTTPNotFound(explanation=unicode(ex))
|
||||
raise webob.exc.HTTPNotFound(explanation=ex.msg)
|
||||
|
||||
@wsgi.serializers(xml=VolumeTypeExtraSpecsTemplate)
|
||||
def index(self, req, type_id):
|
||||
@@ -138,7 +138,7 @@ class VolumeTypeExtraSpecsController(wsgi.Controller):
|
||||
try:
|
||||
db.volume_type_extra_specs_delete(context, type_id, id)
|
||||
except exception.VolumeTypeExtraSpecsNotFound as error:
|
||||
raise webob.exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise webob.exc.HTTPNotFound(explanation=error.msg)
|
||||
|
||||
notifier_info = dict(type_id=type_id, id=id)
|
||||
notifier_api.notify(context, 'volumeTypeExtraSpecs',
|
||||
|
||||
@@ -183,7 +183,7 @@ class VolumeActionsController(wsgi.Controller):
|
||||
try:
|
||||
volume = self.volume_api.get(context, id)
|
||||
except exception.VolumeNotFound as error:
|
||||
raise webob.exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise webob.exc.HTTPNotFound(explanation=error.msg)
|
||||
authorize(context, "upload_image")
|
||||
image_metadata = {"container_format": params.get("container_format",
|
||||
"bare"),
|
||||
@@ -195,7 +195,7 @@ class VolumeActionsController(wsgi.Controller):
|
||||
image_metadata,
|
||||
force)
|
||||
except exception.InvalidVolume as error:
|
||||
raise webob.exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise webob.exc.HTTPBadRequest(explanation=error.msg)
|
||||
except ValueError as error:
|
||||
raise webob.exc.HTTPBadRequest(explanation=unicode(error))
|
||||
except rpc_common.RemoteError as error:
|
||||
|
||||
@@ -113,7 +113,7 @@ class VolumeTransferController(wsgi.Controller):
|
||||
try:
|
||||
transfer = self.transfer_api.get(context, transfer_id=id)
|
||||
except exception.TransferNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
|
||||
return self._view_builder.detail(req, transfer)
|
||||
|
||||
@@ -168,9 +168,9 @@ class VolumeTransferController(wsgi.Controller):
|
||||
try:
|
||||
new_transfer = self.transfer_api.create(context, volume_id, name)
|
||||
except exception.InvalidVolume as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
except exception.VolumeNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
|
||||
transfer = self._view_builder.create(req,
|
||||
dict(new_transfer.iteritems()))
|
||||
@@ -203,9 +203,9 @@ class VolumeTransferController(wsgi.Controller):
|
||||
auth_key)
|
||||
except exception.VolumeSizeExceedsAvailableQuota as error:
|
||||
raise exc.HTTPRequestEntityTooLarge(
|
||||
explanation=error.message, headers={'Retry-After': 0})
|
||||
explanation=error.msg, headers={'Retry-After': 0})
|
||||
except exception.InvalidVolume as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
|
||||
transfer = \
|
||||
self._view_builder.summary(req,
|
||||
@@ -221,7 +221,7 @@ class VolumeTransferController(wsgi.Controller):
|
||||
try:
|
||||
self.transfer_api.delete(context, transfer_id=id)
|
||||
except exception.TransferNotFound as error:
|
||||
raise exc.HTTPNotFound(explanation=unicode(error))
|
||||
raise exc.HTTPNotFound(explanation=error.msg)
|
||||
return webob.Response(status_int=202)
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class VolumeTypeEncryptionController(wsgi.Controller):
|
||||
try:
|
||||
volume_types.get_volume_type(context, type_id)
|
||||
except exception.NotFound as ex:
|
||||
raise webob.exc.HTTPNotFound(explanation=unicode(ex))
|
||||
raise webob.exc.HTTPNotFound(explanation=ex.msg)
|
||||
|
||||
def _check_encryption_input(self, encryption, create=True):
|
||||
if 'key_size' in encryption.keys():
|
||||
|
||||
@@ -588,11 +588,10 @@ class ResourceExceptionHandler(object):
|
||||
return True
|
||||
|
||||
if isinstance(ex_value, exception.NotAuthorized):
|
||||
msg = unicode(ex_value)
|
||||
raise Fault(webob.exc.HTTPForbidden(explanation=msg))
|
||||
raise Fault(webob.exc.HTTPForbidden(explanation=ex_value.msg))
|
||||
elif isinstance(ex_value, exception.Invalid):
|
||||
raise Fault(exception.ConvertedException(
|
||||
code=ex_value.code, explanation=unicode(ex_value)))
|
||||
code=ex_value.code, explanation=ex_value.msg))
|
||||
elif isinstance(ex_value, TypeError):
|
||||
exc_info = (ex_type, ex_value, ex_traceback)
|
||||
LOG.error(_(
|
||||
|
||||
@@ -124,10 +124,10 @@ class Controller(object):
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
except exception.InvalidVolumeMetadata as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
|
||||
except exception.InvalidVolumeMetadataSize as error:
|
||||
raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error))
|
||||
raise exc.HTTPRequestEntityTooLarge(explanation=error.msg)
|
||||
|
||||
@wsgi.serializers(xml=common.MetaItemTemplate)
|
||||
def show(self, req, snapshot_id, id):
|
||||
|
||||
@@ -124,10 +124,10 @@ class Controller(object):
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
except exception.InvalidVolumeMetadata as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
|
||||
except exception.InvalidVolumeMetadataSize as error:
|
||||
raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error))
|
||||
raise exc.HTTPRequestEntityTooLarge(explanation=error.msg)
|
||||
|
||||
@wsgi.serializers(xml=common.MetaItemTemplate)
|
||||
def show(self, req, volume_id, id):
|
||||
|
||||
@@ -124,10 +124,10 @@ class Controller(object):
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
except exception.InvalidVolumeMetadata as error:
|
||||
raise exc.HTTPBadRequest(explanation=unicode(error))
|
||||
raise exc.HTTPBadRequest(explanation=error.msg)
|
||||
|
||||
except exception.InvalidVolumeMetadataSize as error:
|
||||
raise exc.HTTPRequestEntityTooLarge(explanation=unicode(error))
|
||||
raise exc.HTTPRequestEntityTooLarge(explanation=error.msg)
|
||||
|
||||
@wsgi.serializers(xml=common.MetaItemTemplate)
|
||||
def show(self, req, snapshot_id, id):
|
||||
|
||||
@@ -119,8 +119,15 @@ class CinderException(Exception):
|
||||
# at least get the core message out if something happened
|
||||
message = self.message
|
||||
|
||||
# NOTE(luisg): We put the actual message in 'msg' so that we can access
|
||||
# it, because if we try to access the message via 'message' it will be
|
||||
# overshadowed by the class' message attribute
|
||||
self.msg = message
|
||||
super(CinderException, self).__init__(message)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.msg)
|
||||
|
||||
|
||||
class GlanceConnectionFailed(CinderException):
|
||||
message = _("Connection to glance failed") + ": %(reason)s"
|
||||
|
||||
@@ -914,8 +914,7 @@ class BackupsAPITestCase(test.TestCase):
|
||||
self.assertEqual(res.status_int, 413)
|
||||
self.assertEqual(res_dict['overLimit']['code'], 413)
|
||||
self.assertEqual(res_dict['overLimit']['message'],
|
||||
'Maximum number of volumes allowed '
|
||||
'(%(allowed)d) exceeded')
|
||||
'Maximum number of volumes allowed (1) exceeded')
|
||||
|
||||
def test_restore_backup_to_undersized_volume(self):
|
||||
backup_size = 10
|
||||
|
||||
Reference in New Issue
Block a user