Adding common.utils.exception_to_str() to avoid encoding issue
1. Ported common.utils.exception_to_str() back to glance_store. 2. Used exception_to_str() to consistently cast the exception to avoid potential encoding issue. Change-Id: I398ea0e218ebb37b9041cfe82f18b11e614662bf Related-Id: I77478a8eeeefd85bf98138156429df53d0a4c079 Signed-off-by: Zhi Yan Liu <zhiyanl@cn.ibm.com>
This commit is contained in:
parent
7628f2bc56
commit
03331b19f3
@ -545,4 +545,4 @@ class Store(glance_store.driver.Store):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
msg = _('Unable to remove partial image '
|
msg = _('Unable to remove partial image '
|
||||||
'data for image %(iid)s: %(e)s')
|
'data for image %(iid)s: %(e)s')
|
||||||
LOG.error(msg % dict(iid=iid, e=e))
|
LOG.error(msg % dict(iid=iid, e=utils.exception_to_str(e)))
|
||||||
|
@ -518,7 +518,8 @@ def create_bucket_if_missing(bucket, s3_conn):
|
|||||||
s3_conn.create_bucket(bucket, location=location)
|
s3_conn.create_bucket(bucket, location=location)
|
||||||
except S3ResponseError as e:
|
except S3ResponseError as e:
|
||||||
msg = (_("Failed to add bucket to S3.\n"
|
msg = (_("Failed to add bucket to S3.\n"
|
||||||
"Got error from S3: %(e)s") % {'e': e})
|
"Got error from S3: %s.") %
|
||||||
|
utils.exception_to_str(e))
|
||||||
raise glance_store.BackendException(msg)
|
raise glance_store.BackendException(msg)
|
||||||
else:
|
else:
|
||||||
msg = (_("The bucket %(bucket)s does not exist in "
|
msg = (_("The bucket %(bucket)s does not exist in "
|
||||||
|
@ -28,6 +28,7 @@ import urllib
|
|||||||
import glance_store
|
import glance_store
|
||||||
from glance_store._drivers.swift import utils as sutils
|
from glance_store._drivers.swift import utils as sutils
|
||||||
from glance_store.common import auth
|
from glance_store.common import auth
|
||||||
|
from glance_store.common import utils as cutils
|
||||||
from glance_store import driver
|
from glance_store import driver
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store import i18n
|
from glance_store import i18n
|
||||||
@ -118,7 +119,8 @@ def swift_retry_iter(resp_iter, length, store, location, context):
|
|||||||
yield chunk
|
yield chunk
|
||||||
bytes_read += len(chunk)
|
bytes_read += len(chunk)
|
||||||
except swiftclient.ClientException as e:
|
except swiftclient.ClientException as e:
|
||||||
LOG.warn(_(u"Swift exception raised %s") % unicode(e))
|
LOG.warn(_("Swift exception raised %s") %
|
||||||
|
cutils.exception_to_str(e))
|
||||||
|
|
||||||
if bytes_read != length:
|
if bytes_read != length:
|
||||||
if retries == store.conf.glance_store.swift_store_retry_get_count:
|
if retries == store.conf.glance_store.swift_store_retry_get_count:
|
||||||
@ -578,7 +580,7 @@ class BaseStore(driver.Store):
|
|||||||
raise exceptions.Duplicate(message=msg)
|
raise exceptions.Duplicate(message=msg)
|
||||||
|
|
||||||
msg = (_(u"Failed to add object to Swift.\n"
|
msg = (_(u"Failed to add object to Swift.\n"
|
||||||
"Got error from Swift: %s") % unicode(e))
|
"Got error from Swift: %s.") % cutils.exception_to_str(e))
|
||||||
LOG.error(msg)
|
LOG.error(msg)
|
||||||
raise glance_store.BackendException(msg)
|
raise glance_store.BackendException(msg)
|
||||||
|
|
||||||
@ -643,7 +645,8 @@ class BaseStore(driver.Store):
|
|||||||
connection.put_container(container)
|
connection.put_container(container)
|
||||||
except swiftclient.ClientException as e:
|
except swiftclient.ClientException as e:
|
||||||
msg = (_("Failed to add container to Swift.\n"
|
msg = (_("Failed to add container to Swift.\n"
|
||||||
"Got error from Swift: %(e)s") % {'e': e})
|
"Got error from Swift: %s.") %
|
||||||
|
cutils.exception_to_str(e))
|
||||||
raise glance_store.BackendException(msg)
|
raise glance_store.BackendException(msg)
|
||||||
else:
|
else:
|
||||||
msg = (_("The container %(container)s does not exist in "
|
msg = (_("The container %(container)s does not exist in "
|
||||||
|
@ -20,6 +20,7 @@ from oslo.config import cfg
|
|||||||
from stevedore import driver
|
from stevedore import driver
|
||||||
from stevedore import extension
|
from stevedore import extension
|
||||||
|
|
||||||
|
from glance_store.common import utils
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store import i18n
|
from glance_store import i18n
|
||||||
from glance_store import location
|
from glance_store import location
|
||||||
@ -173,7 +174,7 @@ def _load_stores(conf):
|
|||||||
|
|
||||||
yield (store_entry, store_instance)
|
yield (store_entry, store_instance)
|
||||||
|
|
||||||
except exceptions.BadStoreConfiguration as e:
|
except exceptions.BadStoreConfiguration:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
@ -301,7 +302,7 @@ def safe_delete_from_backend(uri, image_id, context=None):
|
|||||||
msg = _('Failed to delete image %s in store from URI')
|
msg = _('Failed to delete image %s in store from URI')
|
||||||
LOG.warn(msg % image_id)
|
LOG.warn(msg % image_id)
|
||||||
except exceptions.StoreDeleteNotSupported as e:
|
except exceptions.StoreDeleteNotSupported as e:
|
||||||
LOG.warn(str(e))
|
LOG.warn(utils.exception_to_str(e))
|
||||||
except exceptions.UnsupportedBackend:
|
except exceptions.UnsupportedBackend:
|
||||||
exc_type = sys.exc_info()[0].__name__
|
exc_type = sys.exc_info()[0].__name__
|
||||||
msg = (_('Failed to delete image %(image_id)s '
|
msg = (_('Failed to delete image %(image_id)s '
|
||||||
@ -361,9 +362,9 @@ def store_add_to_backend(image_id, data, size, store, context=None):
|
|||||||
except exceptions.BackendException as e:
|
except exceptions.BackendException as e:
|
||||||
e_msg = (_("A bad metadata structure was returned from the "
|
e_msg = (_("A bad metadata structure was returned from the "
|
||||||
"%(driver)s storage driver: %(metadata)s. %(e)s.") %
|
"%(driver)s storage driver: %(metadata)s. %(e)s.") %
|
||||||
dict(driver=unicode(store),
|
dict(driver=utils.exception_to_str(store),
|
||||||
metadata=unicode(metadata),
|
metadata=utils.exception_to_str(metadata),
|
||||||
e=unicode(e)))
|
e=utils.exception_to_str(e)))
|
||||||
LOG.error(e_msg)
|
LOG.error(e_msg)
|
||||||
raise exceptions.BackendException(e_msg)
|
raise exceptions.BackendException(e_msg)
|
||||||
return (location, size, checksum, metadata)
|
return (location, size, checksum, metadata)
|
||||||
|
@ -26,6 +26,7 @@ from oslo.config import cfg
|
|||||||
from paste import deploy
|
from paste import deploy
|
||||||
|
|
||||||
from glance.version import version_info as version
|
from glance.version import version_info as version
|
||||||
|
from glance_store.common import utils
|
||||||
|
|
||||||
paste_deploy_opts = [
|
paste_deploy_opts = [
|
||||||
cfg.StrOpt('flavor',
|
cfg.StrOpt('flavor',
|
||||||
@ -213,6 +214,6 @@ def load_paste_app(app_name, flavor=None, conf_file=None):
|
|||||||
"configuration file %(conf_file)s."
|
"configuration file %(conf_file)s."
|
||||||
"\nGot: %(e)r") % {'app_name': app_name,
|
"\nGot: %(e)r") % {'app_name': app_name,
|
||||||
'conf_file': conf_file,
|
'conf_file': conf_file,
|
||||||
'e': e})
|
'e': utils.exception_to_str(e)})
|
||||||
logger.error(msg)
|
logger.error(msg)
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
@ -25,6 +25,9 @@ try:
|
|||||||
from eventlet import sleep
|
from eventlet import sleep
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
import six
|
||||||
|
|
||||||
|
from glance_store.openstack.common import strutils
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
@ -137,3 +140,15 @@ class CooperativeReader(object):
|
|||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return cooperative_iter(self.fd.__iter__())
|
return cooperative_iter(self.fd.__iter__())
|
||||||
|
|
||||||
|
|
||||||
|
def exception_to_str(exc):
|
||||||
|
try:
|
||||||
|
error = six.text_type(exc)
|
||||||
|
except UnicodeError:
|
||||||
|
try:
|
||||||
|
error = str(exc)
|
||||||
|
except UnicodeError:
|
||||||
|
error = ("Caught '%(exception)s' exception." %
|
||||||
|
{"exception": exc.__class__.__name__})
|
||||||
|
return strutils.safe_encode(error, errors='ignore')
|
||||||
|
@ -20,26 +20,14 @@ import logging
|
|||||||
|
|
||||||
from oslo.config import cfg
|
from oslo.config import cfg
|
||||||
|
|
||||||
|
from glance_store.common import utils
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store.i18n import _
|
from glance_store.i18n import _
|
||||||
from glance_store.openstack.common import importutils
|
from glance_store.openstack.common import importutils
|
||||||
from glance_store.openstack.common import strutils
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _exception_to_unicode(exc):
|
|
||||||
try:
|
|
||||||
return unicode(exc)
|
|
||||||
except UnicodeError:
|
|
||||||
try:
|
|
||||||
return strutils.safe_decode(str(exc), errors='ignore')
|
|
||||||
except UnicodeError:
|
|
||||||
msg = (_("Caught '%(exception)s' exception.") %
|
|
||||||
{"exception": exc.__class__.__name__})
|
|
||||||
return strutils.safe_decode(msg, errors='ignore')
|
|
||||||
|
|
||||||
|
|
||||||
class Store(object):
|
class Store(object):
|
||||||
|
|
||||||
OPTIONS = None
|
OPTIONS = None
|
||||||
@ -79,7 +67,7 @@ class Store(object):
|
|||||||
self._add = self.add
|
self._add = self.add
|
||||||
self.add = self.add_disabled
|
self.add = self.add_disabled
|
||||||
msg = (_(u"Failed to configure store correctly: %s "
|
msg = (_(u"Failed to configure store correctly: %s "
|
||||||
"Disabling add method.") % _exception_to_unicode(e))
|
"Disabling add method.") % utils.exception_to_str(e))
|
||||||
LOG.warn(msg)
|
LOG.warn(msg)
|
||||||
|
|
||||||
def get_schemes(self):
|
def get_schemes(self):
|
||||||
|
@ -14,8 +14,6 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import glance_store as store
|
import glance_store as store
|
||||||
from glance_store import driver
|
|
||||||
from glance_store.openstack.common.gettextutils import _
|
|
||||||
from glance_store.tests import base
|
from glance_store.tests import base
|
||||||
|
|
||||||
|
|
||||||
@ -25,27 +23,6 @@ class TestStoreBase(base.StoreBaseTest):
|
|||||||
super(TestStoreBase, self).setUp()
|
super(TestStoreBase, self).setUp()
|
||||||
self.config(default_store='file', group='glance_store')
|
self.config(default_store='file', group='glance_store')
|
||||||
|
|
||||||
def test_exception_to_unicode(self):
|
|
||||||
class FakeException(Exception):
|
|
||||||
def __str__(self):
|
|
||||||
raise UnicodeError()
|
|
||||||
|
|
||||||
exc = Exception('error message')
|
|
||||||
ret = driver._exception_to_unicode(exc)
|
|
||||||
self.assertIsInstance(ret, unicode)
|
|
||||||
self.assertEqual(ret, 'error message')
|
|
||||||
|
|
||||||
exc = Exception('\xa5 error message')
|
|
||||||
ret = driver._exception_to_unicode(exc)
|
|
||||||
self.assertIsInstance(ret, unicode)
|
|
||||||
self.assertEqual(ret, ' error message')
|
|
||||||
|
|
||||||
exc = FakeException('\xa5 error message')
|
|
||||||
ret = driver._exception_to_unicode(exc)
|
|
||||||
self.assertIsInstance(ret, unicode)
|
|
||||||
self.assertEqual(ret, _("Caught '%(exception)s' exception.") %
|
|
||||||
{'exception': 'FakeException'})
|
|
||||||
|
|
||||||
def test_create_store_exclude_unconfigurable_drivers(self):
|
def test_create_store_exclude_unconfigurable_drivers(self):
|
||||||
self.config(stores=["no_conf", "file"], group='glance_store')
|
self.config(stores=["no_conf", "file"], group='glance_store')
|
||||||
count = store.create_stores(self.conf)
|
count = store.create_stores(self.conf)
|
||||||
|
@ -33,6 +33,7 @@ from glance_store._drivers.swift import utils as sutils
|
|||||||
from glance_store import backend
|
from glance_store import backend
|
||||||
from glance_store import BackendException
|
from glance_store import BackendException
|
||||||
from glance_store.common import auth
|
from glance_store.common import auth
|
||||||
|
from glance_store.common import utils
|
||||||
from glance_store import exceptions
|
from glance_store import exceptions
|
||||||
from glance_store.location import get_location_from_uri
|
from glance_store.location import get_location_from_uri
|
||||||
from glance_store.openstack.common import context
|
from glance_store.openstack.common import context
|
||||||
@ -479,7 +480,7 @@ class SwiftTests(object):
|
|||||||
except BackendException as e:
|
except BackendException as e:
|
||||||
exception_caught = True
|
exception_caught = True
|
||||||
self.assertIn("container noexist does not exist "
|
self.assertIn("container noexist does not exist "
|
||||||
"in Swift", unicode(e))
|
"in Swift", utils.exception_to_str(e))
|
||||||
self.assertTrue(exception_caught)
|
self.assertTrue(exception_caught)
|
||||||
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 0)
|
self.assertEqual(SWIFT_PUT_OBJECT_CALLS, 0)
|
||||||
|
|
||||||
|
37
tests/unit/test_utils.py
Normal file
37
tests/unit/test_utils.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# Copyright 2014 OpenStack Foundation
|
||||||
|
# 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 oslotest import base
|
||||||
|
|
||||||
|
from glance_store.common import utils
|
||||||
|
|
||||||
|
|
||||||
|
class TestUtils(base.BaseTestCase):
|
||||||
|
"""Test routines in glance_store.common.utils"""
|
||||||
|
|
||||||
|
def test_exception_to_str(self):
|
||||||
|
class FakeException(Exception):
|
||||||
|
def __str__(self):
|
||||||
|
raise UnicodeError()
|
||||||
|
|
||||||
|
ret = utils.exception_to_str(Exception('error message'))
|
||||||
|
self.assertEqual(ret, 'error message')
|
||||||
|
|
||||||
|
ret = utils.exception_to_str(Exception('\xa5 error message'))
|
||||||
|
self.assertEqual(ret, ' error message')
|
||||||
|
|
||||||
|
ret = utils.exception_to_str(FakeException('\xa5 error message'))
|
||||||
|
self.assertEqual(ret, "Caught '%(exception)s' exception." %
|
||||||
|
{'exception': 'FakeException'})
|
Loading…
Reference in New Issue
Block a user