Remove use of unicode on exceptions

Casting exceptions to unicode using unicode() can interfere
with the proper translation of the exception message.  This
is especially true when lazy translation is enabled, since it
causes the exception message to be translated immediately using
the default locale.

This is the same problem caused by using str on exceptions,
which was fixed by https://review.openstack.org/#/c/116054/

In addition to fixing these cases, this patch updates
hacking check N325, which checks for the use of str() on
exceptions, to also check for the use of unicode().

In order to make it clear which cases that cannot be caught
by the hacking check have been inspected, they have been
converted to using six.text_type() instead of unicode().

Closes-bug: #1380806
Change-Id: I87bb94fa76458e028beba28d092320057b53f70a
This commit is contained in:
James Carey 2014-10-17 13:14:26 -07:00
parent 502b420941
commit 6683905b53
27 changed files with 113 additions and 77 deletions

View File

@ -37,7 +37,7 @@ Nova Specific Commandments
- [N322] Method's default argument shouldn't be mutable
- [N323] Ensure that the _() function is explicitly imported to ensure proper translations.
- [N324] Ensure that jsonutils.%(fun)s must be used instead of json.%(fun)s
- [N325] str() cannot be used on an exception. Remove use or use six.text_type()
- [N325] str() and unicode() cannot be used on an exception. Remove use or use six.text_type()
- [N326] Translated messages cannot be concatenated. String should be included in translated message.
- [N327] assert_called_once() is not a valid method

View File

@ -87,7 +87,7 @@ class FaultWrapper(wsgi.Middleware):
try:
return req.get_response(self.application)
except Exception as ex:
LOG.exception(_("FaultWrapper: %s"), unicode(ex))
LOG.exception(_("FaultWrapper: %s"), ex)
return faults.Fault(webob.exc.HTTPInternalServerError())
@ -321,7 +321,7 @@ class Requestify(wsgi.Middleware):
except KeyError:
raise webob.exc.HTTPBadRequest()
except exception.InvalidRequest as err:
raise webob.exc.HTTPBadRequest(explanation=unicode(err))
raise webob.exc.HTTPBadRequest(explanation=six.text_type(err))
LOG.debug('action: %s', action)
for key, value in args.items():
@ -506,9 +506,9 @@ def ec2_error_ex(ex, req, code=None, message=None, unexpected=False):
request_id = context.request_id
log_msg_args = {
'ex_name': type(ex).__name__,
'ex_str': unicode(ex)
'ex_str': ex
}
log_fun(log_msg % log_msg_args, context=context)
log_fun(log_msg, log_msg_args, context=context)
if ex.args and not message and (not unexpected or status < 500):
message = unicode(ex.args[0])

View File

@ -97,7 +97,7 @@ class AgentController(object):
md5hash = para['md5hash']
version = para['version']
except (TypeError, KeyError) as ex:
msg = _("Invalid request body: %s") % unicode(ex)
msg = _("Invalid request body: %s") % ex
raise webob.exc.HTTPBadRequest(explanation=msg)
try:
@ -115,7 +115,7 @@ class AgentController(object):
agent.md5hash = md5hash
agent.save()
except ValueError as ex:
msg = _("Invalid request body: %s") % unicode(ex)
msg = _("Invalid request body: %s") % ex
raise webob.exc.HTTPBadRequest(explanation=msg)
except exception.AgentBuildNotFound as ex:
raise webob.exc.HTTPNotFound(explanation=ex.format_message())
@ -153,7 +153,7 @@ class AgentController(object):
url = agent['url']
md5hash = agent['md5hash']
except (TypeError, KeyError) as ex:
msg = _("Invalid request body: %s") % unicode(ex)
msg = _("Invalid request body: %s") % ex
raise webob.exc.HTTPBadRequest(explanation=msg)
try:

View File

@ -53,7 +53,7 @@ class CloudpipeUpdateController(wsgi.Controller):
network.vpn_public_port = vpn_port
network.save()
except (TypeError, KeyError, ValueError) as ex:
msg = _("Invalid request body: %s") % unicode(ex)
msg = _("Invalid request body: %s") % ex
raise webob.exc.HTTPBadRequest(explanation=msg)
return webob.Response(status_int=202)

View File

@ -13,6 +13,7 @@
# under the License.
from xml.dom import minidom
import six
import webob
from webob import exc
@ -119,7 +120,7 @@ class SecurityGroupDefaultRulesController(sg.SecurityGroupControllerBase):
ip_protocol=sg_rule.get('ip_protocol'),
cidr=sg_rule.get('cidr'))
except Exception as exp:
raise exc.HTTPBadRequest(explanation=unicode(exp))
raise exc.HTTPBadRequest(explanation=six.text_type(exp))
if values is None:
msg = _('Not enough parameters to build a valid rule.')

View File

@ -20,6 +20,7 @@ import contextlib
from xml.dom import minidom
from oslo.serialization import jsonutils
import six
import webob
from webob import exc
@ -390,7 +391,7 @@ class SecurityGroupRulesController(SecurityGroupControllerBase):
cidr=sg_rule.get('cidr'),
group_id=sg_rule.get('group_id'))
except Exception as exp:
raise exc.HTTPBadRequest(explanation=unicode(exp))
raise exc.HTTPBadRequest(explanation=six.text_type(exp))
if new_rule is None:
msg = _("Not enough parameters to build a valid rule.")

View File

@ -17,6 +17,7 @@ import datetime
import iso8601
from oslo.utils import timeutils
import six
import six.moves.urllib.parse as urlparse
from webob import exc
@ -55,7 +56,7 @@ def parse_strtime(dstr, fmt):
try:
return timeutils.parse_strtime(dstr, fmt)
except (TypeError, ValueError) as e:
raise exception.InvalidStrTime(reason=unicode(e))
raise exception.InvalidStrTime(reason=six.text_type(e))
class SimpleTenantUsageTemplate(xmlutil.TemplateBuilder):

View File

@ -48,7 +48,7 @@ class LoadedExtensionInfo(object):
' '.join(extension.__doc__.strip().split()))
LOG.debug('Ext version: %i', extension.version)
except AttributeError as ex:
LOG.exception(_("Exception loading extension: %s"), unicode(ex))
LOG.exception(_("Exception loading extension: %s"), ex)
return False
return True

View File

@ -549,7 +549,7 @@ class ServersController(wsgi.Controller):
'err_msg': err.value}
raise exc.HTTPBadRequest(explanation=msg)
except UnicodeDecodeError as error:
msg = "UnicodeError: %s" % unicode(error)
msg = "UnicodeError: %s" % error
raise exc.HTTPBadRequest(explanation=msg)
except (exception.ImageNotActive,
exception.FlavorDiskTooSmall,

View File

@ -17,6 +17,7 @@ import datetime
import iso8601
from oslo.utils import timeutils
import six
import six.moves.urllib.parse as urlparse
from webob import exc
@ -37,7 +38,7 @@ def parse_strtime(dstr, fmt):
try:
return timeutils.parse_strtime(dstr, fmt)
except (TypeError, ValueError) as e:
raise exception.InvalidStrTime(reason=unicode(e))
raise exception.InvalidStrTime(reason=six.text_type(e))
class SimpleTenantUsageController(object):

View File

@ -987,7 +987,7 @@ class Controller(wsgi.Controller):
'err_msg': err.value}
raise exc.HTTPBadRequest(explanation=msg)
except UnicodeDecodeError as error:
msg = "UnicodeError: %s" % unicode(error)
msg = "UnicodeError: %s" % error
raise exc.HTTPBadRequest(explanation=msg)
except (exception.ImageNotActive,
exception.FlavorDiskTooSmall,

View File

@ -239,7 +239,7 @@ class ExtensionManager(object):
LOG.debug('Ext namespace: %s', extension.namespace)
LOG.debug('Ext updated: %s', extension.updated)
except AttributeError as ex:
LOG.exception(_("Exception loading extension: %s"), unicode(ex))
LOG.exception(_("Exception loading extension: %s"), ex)
return False
return True

View File

@ -662,10 +662,10 @@ class ResourceExceptionHandler(object):
exc_info=exc_info)
raise Fault(webob.exc.HTTPBadRequest())
elif isinstance(ex_value, Fault):
LOG.info(_LI("Fault thrown: %s"), unicode(ex_value))
LOG.info(_LI("Fault thrown: %s"), ex_value)
raise ex_value
elif isinstance(ex_value, webob.exc.HTTPException):
LOG.info(_LI("HTTP exception thrown: %s"), unicode(ex_value))
LOG.info(_LI("HTTP exception thrown: %s"), ex_value)
raise Fault(ex_value)
# We didn't handle the exception

View File

@ -1487,7 +1487,7 @@ class ComputeManager(manager.Manager):
self._log_original_error(exc_info, instance.uuid)
raise exception.RescheduledException(
instance_uuid=instance.uuid,
reason=unicode(exc_info[1]))
reason=six.text_type(exc_info[1]))
else:
# not re-scheduling, go to error:
raise exc_info[0], exc_info[1], exc_info[2]
@ -2415,7 +2415,7 @@ class ComputeManager(manager.Manager):
exc_info = sys.exc_info()
LOG.warn(_LW('Failed to delete volume: %(volume_id)s due '
'to %(exc)s'), {'volume_id': bdm.volume_id,
'exc': unicode(exc)})
'exc': exc})
if exc_info is not None and raise_exc:
six.reraise(exc_info[0], exc_info[1], exc_info[2])
@ -3264,7 +3264,7 @@ class ComputeManager(manager.Manager):
instance=instance)
raise exception.InstanceNotRescuable(
instance_id=instance.uuid,
reason=_("Driver Error: %s") % unicode(e))
reason=_("Driver Error: %s") % e)
self.conductor_api.notify_usage_exists(context, instance,
current_period=True)
@ -5933,7 +5933,7 @@ class ComputeManager(manager.Manager):
except Exception as e:
LOG.warning(_("Periodic reclaim failed to delete "
"instance: %s"),
unicode(e), instance=instance)
e, instance=instance)
@periodic_task.periodic_task
def update_available_resource(self, context):
@ -6044,7 +6044,7 @@ class ComputeManager(manager.Manager):
except Exception as e:
LOG.warning(_("Periodic cleanup failed to delete "
"instance: %s"),
unicode(e), instance=instance)
e, instance=instance)
else:
raise Exception(_("Unrecognized value '%s'"
" for CONF.running_deleted_"

View File

@ -358,20 +358,21 @@ def check_assert_called_once(logical_line, filename):
yield (pos, msg)
class CheckForStrExc(BaseASTChecker):
"""Checks for the use of str() on an exception.
class CheckForStrUnicodeExc(BaseASTChecker):
"""Checks for the use of str() or unicode() on an exception.
This currently only handles the case where str() is used in
the scope of an exception handler. If the exception is passed
into a function, returned from an assertRaises, or used on an
exception created in the same scope, this does not catch it.
This currently only handles the case where str() or unicode()
is used in the scope of an exception handler. If the exception
is passed into a function, returned from an assertRaises, or
used on an exception created in the same scope, this does not
catch it.
"""
CHECK_DESC = ('N325 str() cannot be used on an exception. '
'Remove or use six.text_type()')
CHECK_DESC = ('N325 str() and unicode() cannot be used on an '
'exception. Remove or use six.text_type()')
def __init__(self, tree, filename):
super(CheckForStrExc, self).__init__(tree, filename)
super(CheckForStrUnicodeExc, self).__init__(tree, filename)
self.name = []
self.already_checked = []
@ -379,19 +380,19 @@ class CheckForStrExc(BaseASTChecker):
for handler in node.handlers:
if handler.name:
self.name.append(handler.name.id)
super(CheckForStrExc, self).generic_visit(node)
super(CheckForStrUnicodeExc, self).generic_visit(node)
self.name = self.name[:-1]
else:
super(CheckForStrExc, self).generic_visit(node)
super(CheckForStrUnicodeExc, self).generic_visit(node)
def visit_Call(self, node):
if self._check_call_names(node, ['str']):
if self._check_call_names(node, ['str', 'unicode']):
if node not in self.already_checked:
self.already_checked.append(node)
if isinstance(node.args[0], ast.Name):
if node.args[0].id in self.name:
self.add_error(node.args[0])
super(CheckForStrExc, self).generic_visit(node)
super(CheckForStrUnicodeExc, self).generic_visit(node)
class CheckForTransAdd(BaseASTChecker):
@ -435,5 +436,5 @@ def factory(register):
register(check_explicit_underscore_import)
register(use_jsonutils)
register(check_assert_called_once)
register(CheckForStrExc)
register(CheckForStrUnicodeExc)
register(CheckForTransAdd)

View File

@ -612,18 +612,18 @@ def _translate_image_exception(image_id, exc_value):
if isinstance(exc_value, glanceclient.exc.NotFound):
return exception.ImageNotFound(image_id=image_id)
if isinstance(exc_value, glanceclient.exc.BadRequest):
return exception.Invalid(unicode(exc_value))
return exception.Invalid(six.text_type(exc_value))
return exc_value
def _translate_plain_exception(exc_value):
if isinstance(exc_value, (glanceclient.exc.Forbidden,
glanceclient.exc.Unauthorized)):
return exception.Forbidden(unicode(exc_value))
return exception.Forbidden(six.text_type(exc_value))
if isinstance(exc_value, glanceclient.exc.NotFound):
return exception.NotFound(unicode(exc_value))
return exception.NotFound(six.text_type(exc_value))
if isinstance(exc_value, glanceclient.exc.BadRequest):
return exception.Invalid(unicode(exc_value))
return exception.Invalid(six.text_type(exc_value))
return exc_value

View File

@ -21,6 +21,7 @@ import uuid
from neutronclient.common import exceptions as neutron_client_exc
from oslo.config import cfg
from oslo.utils import excutils
import six
from nova.api.openstack import extensions
from nova.compute import flavors
@ -1151,9 +1152,9 @@ class API(base_api.NetworkAPI):
fip = client.create_floatingip(param)
except (neutron_client_exc.IpAddressGenerationFailureClient,
neutron_client_exc.ExternalIpAddressExhaustedClient) as e:
raise exception.NoMoreFloatingIps(unicode(e))
raise exception.NoMoreFloatingIps(six.text_type(e))
except neutron_client_exc.OverQuotaClient as e:
raise exception.FloatingIpLimitExceeded(unicode(e))
raise exception.FloatingIpLimitExceeded(six.text_type(e))
return fip['floatingip']['floating_ip_address']

View File

@ -62,7 +62,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
# quota
raise exc.HTTPBadRequest()
elif e.status_code == 409:
self.raise_over_quota(unicode(e))
self.raise_over_quota(six.text_type(e))
raise exc_info[0], exc_info[1], exc_info[2]
return self._convert_to_nova_security_group_format(security_group)
@ -136,7 +136,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
exc_info = sys.exc_info()
if e.status_code == 404:
LOG.debug("Neutron security group %s not found", name)
self.raise_not_found(unicode(e))
self.raise_not_found(six.text_type(e))
else:
LOG.error(_("Neutron Error: %s"), e)
raise exc_info[0], exc_info[1], exc_info[2]
@ -181,9 +181,9 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
except n_exc.NeutronClientException as e:
exc_info = sys.exc_info()
if e.status_code == 404:
self.raise_not_found(unicode(e))
self.raise_not_found(six.text_type(e))
elif e.status_code == 409:
self.raise_invalid_property(unicode(e))
self.raise_invalid_property(six.text_type(e))
else:
LOG.error(_("Neutron Error: %s"), e)
raise exc_info[0], exc_info[1], exc_info[2]
@ -207,11 +207,11 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
if e.status_code == 404:
LOG.exception(_("Neutron Error getting security group %s"),
name)
self.raise_not_found(unicode(e))
self.raise_not_found(six.text_type(e))
elif e.status_code == 409:
LOG.exception(_("Neutron Error adding rules to security "
"group %s"), name)
self.raise_over_quota(unicode(e))
self.raise_over_quota(six.text_type(e))
else:
LOG.exception(_("Neutron Error:"))
raise exc_info[0], exc_info[1], exc_info[2]
@ -278,7 +278,7 @@ class SecurityGroupAPI(security_group_base.SecurityGroupBase):
exc_info = sys.exc_info()
if e.status_code == 404:
LOG.debug("Neutron security group rule %s not found", id)
self.raise_not_found(unicode(e))
self.raise_not_found(six.text_type(e))
else:
LOG.error(_("Neutron Error: %s"), e)
raise exc_info[0], exc_info[1], exc_info[2]

View File

@ -21,6 +21,7 @@ import xml.dom.minidom as minidom
from lxml import etree
import mock
import six
from testtools import matchers
import webob
import webob.exc
@ -380,7 +381,7 @@ class MiscFunctionsTest(test.TestCase):
common.raise_http_conflict_for_instance_invalid_state(exc,
'meow', 'fake_server_id')
except webob.exc.HTTPConflict as e:
self.assertEqual(unicode(e),
self.assertEqual(six.text_type(e),
"Cannot 'meow' instance fake_server_id while it is in "
"fake_attr fake_state")
else:

View File

@ -15,6 +15,7 @@
"""Tests for keypair API."""
from oslo.config import cfg
import six
from nova.compute import api as compute_api
from nova import context
@ -117,7 +118,7 @@ class CreateImportSharedTestMixIn(object):
exc = self.assertRaises(exc_class, func, self.ctxt, self.ctxt.user_id,
name, *args)
self.assertEqual(expected_message, unicode(exc))
self.assertEqual(expected_message, six.text_type(exc))
def assertInvalidKeypair(self, expected_message, name):
msg = _('Keypair data is invalid: %s') % expected_message
@ -188,7 +189,7 @@ class ImportKeypairTestCase(KeypairAPITestCase, CreateImportSharedTestMixIn):
self.ctxt, self.ctxt.user_id, 'foo',
'bad key data')
msg = u'Keypair data is invalid: failed to generate fingerprint'
self.assertEqual(msg, unicode(exc))
self.assertEqual(msg, six.text_type(exc))
class GetKeypairTestCase(KeypairAPITestCase):

View File

@ -6554,7 +6554,7 @@ class Ec2TestCase(test.TestCase):
try:
method(self.ctxt, value)
except exception.NotFound as exc:
self.assertIn(unicode(value), unicode(exc))
self.assertIn(six.text_type(value), six.text_type(exc))
check_exc_format(db.get_ec2_instance_id_by_uuid, 'fake')
check_exc_format(db.get_instance_uuid_by_ec2_id, 123456)

View File

@ -13,6 +13,7 @@
import mock
import six
from nova import exception
from nova import objects
@ -52,7 +53,7 @@ class PciAddressTestCase(test.NoDBTestCase):
msg = ('Invalid PCI Whitelist: '
'The PCI address 0000:0a:00.%s has an invalid function.'
% (devspec.MAX_FUNC + 1))
self.assertEqual(msg, unicode(exc))
self.assertEqual(msg, six.text_type(exc))
def test_max_domain(self):
pci_info = ('{"address": "%x:0a:00.5", "physical_network":"hr_net"}'
@ -61,7 +62,7 @@ class PciAddressTestCase(test.NoDBTestCase):
devspec.PciDeviceSpec, pci_info)
msg = ('Invalid PCI devices Whitelist config invalid domain %x'
% (devspec.MAX_DOMAIN + 1))
self.assertEqual(msg, unicode(exc))
self.assertEqual(msg, six.text_type(exc))
def test_max_bus(self):
pci_info = ('{"address": "0000:%x:00.5", "physical_network":"hr_net"}'
@ -70,7 +71,7 @@ class PciAddressTestCase(test.NoDBTestCase):
devspec.PciDeviceSpec, pci_info)
msg = ('Invalid PCI devices Whitelist config invalid bus %x'
% (devspec.MAX_BUS + 1))
self.assertEqual(msg, unicode(exc))
self.assertEqual(msg, six.text_type(exc))
def test_max_slot(self):
pci_info = ('{"address": "0000:0a:%x.5", "physical_network":"hr_net"}'
@ -79,7 +80,7 @@ class PciAddressTestCase(test.NoDBTestCase):
devspec.PciDeviceSpec, pci_info)
msg = ('Invalid PCI devices Whitelist config invalid slot %x'
% (devspec.MAX_SLOT + 1))
self.assertEqual(msg, unicode(exc))
self.assertEqual(msg, six.text_type(exc))
def test_address_is_undefined(self):
pci_info = '{"vendor_id":"8086", "product_id":"5057"}'
@ -121,7 +122,7 @@ class PciDevSpecTestCase(test.NoDBTestCase):
exc = self.assertRaises(exception.PciConfigInvalidWhitelist,
devspec.PciDeviceSpec, pci_info)
self.assertEqual("Invalid PCI devices Whitelist config "
"invalid vendor_id 80860", unicode(exc))
"invalid vendor_id 80860", six.text_type(exc))
def test_invalid_product_id(self):
pci_info = ('{"vendor_id": "8086","address": "*: *: *.5", ' +
@ -135,7 +136,7 @@ class PciDevSpecTestCase(test.NoDBTestCase):
exc = self.assertRaises(exception.PciConfigInvalidWhitelist,
devspec.PciDeviceSpec, pci_info)
self.assertEqual("Invalid PCI devices Whitelist config "
"invalid product_id 50570", unicode(exc))
"invalid product_id 50570", six.text_type(exc))
def test_devname_and_address(self):
pci_info = ('{"devname": "eth0", "vendor_id":"8086", ' +
@ -156,7 +157,7 @@ class PciDevSpecTestCase(test.NoDBTestCase):
pci_info = '{"devname": "lo", "physical_network": "hr_net"}'
exc = self.assertRaises(exception.PciDeviceNotFoundById,
devspec.PciDeviceSpec, pci_info)
self.assertEqual('PCI device lo not found', unicode(exc))
self.assertEqual('PCI device lo not found', six.text_type(exc))
def test_pci_obj(self):
pci_info = ('{"vendor_id": "8086","address": "*:*:*.5", ' +

View File

@ -16,6 +16,8 @@
import inspect
import six
from nova import context
from nova import exception
from nova import test
@ -67,10 +69,10 @@ class NovaExceptionTestCase(test.NoDBTestCase):
msg_fmt = "default message"
exc = FakeNovaException()
self.assertEqual(unicode(exc), 'default message')
self.assertEqual(six.text_type(exc), 'default message')
def test_error_msg(self):
self.assertEqual(unicode(exception.NovaException('test')),
self.assertEqual(six.text_type(exception.NovaException('test')),
'test')
def test_default_error_msg_with_kwargs(self):
@ -78,7 +80,7 @@ class NovaExceptionTestCase(test.NoDBTestCase):
msg_fmt = "default message: %(code)s"
exc = FakeNovaException(code=500)
self.assertEqual(unicode(exc), 'default message: 500')
self.assertEqual(six.text_type(exc), 'default message: 500')
self.assertEqual(exc.message, 'default message: 500')
def test_error_msg_exception_with_kwargs(self):
@ -86,7 +88,7 @@ class NovaExceptionTestCase(test.NoDBTestCase):
msg_fmt = "default message: %(misspelled_code)s"
exc = FakeNovaException(code=500, misspelled_code='blah')
self.assertEqual(unicode(exc), 'default message: blah')
self.assertEqual(six.text_type(exc), 'default message: blah')
self.assertEqual(exc.message, 'default message: blah')
def test_default_error_code(self):
@ -115,7 +117,7 @@ class NovaExceptionTestCase(test.NoDBTestCase):
msg_fmt = "some message"
exc = FakeNovaException()
self.assertEqual(unicode(exc), exc.format_message())
self.assertEqual(six.text_type(exc), exc.format_message())
def test_format_message_remote(self):
class FakeNovaException_Remote(exception.NovaException):
@ -125,7 +127,7 @@ class NovaExceptionTestCase(test.NoDBTestCase):
return u"print the whole trace"
exc = FakeNovaException_Remote()
self.assertEqual(unicode(exc), u"print the whole trace")
self.assertEqual(six.text_type(exc), u"print the whole trace")
self.assertEqual(exc.format_message(), "some message")
def test_format_message_remote_error(self):

View File

@ -300,9 +300,9 @@ class HackingTestCase(test.NoDBTestCase):
self._assert_has_errors(code, checker, expected_errors=errors,
filename='nova/tests/test_assert.py')
def test_str_exception(self):
def test_str_unicode_exception(self):
checker = checks.CheckForStrExc
checker = checks.CheckForStrUnicodeExc
code = """
def f(a, b):
try:
@ -314,6 +314,17 @@ class HackingTestCase(test.NoDBTestCase):
errors = [(5, 16, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
code = """
def f(a, b):
try:
p = unicode(a) + str(b)
except ValueError as e:
p = e
return p
"""
errors = []
self._assert_has_errors(code, checker, expected_errors=errors)
code = """
def f(a, b):
try:
@ -322,7 +333,7 @@ class HackingTestCase(test.NoDBTestCase):
p = unicode(e)
return p
"""
errors = []
errors = [(5, 20, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
code = """
@ -334,12 +345,27 @@ class HackingTestCase(test.NoDBTestCase):
p = unicode(a) + unicode(b)
except ValueError as ve:
p = str(e) + str(ve)
p = unicode(e)
p = e
return p
"""
errors = [(8, 20, 'N325'), (8, 29, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
code = """
def f(a, b):
try:
p = str(a) + str(b)
except ValueError as e:
try:
p = unicode(a) + unicode(b)
except ValueError as ve:
p = str(e) + unicode(ve)
p = str(e)
return p
"""
errors = [(8, 20, 'N325'), (8, 33, 'N325'), (9, 16, 'N325')]
self._assert_has_errors(code, checker, expected_errors=errors)
def test_trans_add(self):
checker = checks.CheckForTransAdd

View File

@ -5175,8 +5175,7 @@ class LibvirtDriver(driver.ComputeDriver):
ret = self._conn.compareCPU(cpu.to_xml(), 0)
except libvirt.libvirtError as e:
with excutils.save_and_reraise_exception():
ret = unicode(e)
LOG.error(m, {'ret': ret, 'u': u})
LOG.error(m, {'ret': e, 'u': u})
if ret <= 0:
LOG.error(m, {'ret': ret, 'u': u})

View File

@ -276,7 +276,7 @@ class Image(object):
except (TypeError, ValueError) as e:
msg = (_("Could not load line %(line)s, got error "
"%(error)s") %
{'line': line, 'error': unicode(e)})
{'line': line, 'error': e})
raise exception.InvalidDiskInfo(reason=msg)
@utils.synchronized(self.disk_info_path, external=False,
@ -313,7 +313,7 @@ class Image(object):
fileutils.ensure_tree(os.path.dirname(self.disk_info_path))
write_to_disk_info_file()
except OSError as e:
raise exception.DiskInfoReadWriteFail(reason=unicode(e))
raise exception.DiskInfoReadWriteFail(reason=six.text_type(e))
return driver_format
@staticmethod

View File

@ -395,7 +395,7 @@ class API(object):
except cinder_exception.OverLimit:
raise exception.OverQuota(overs='volumes')
except cinder_exception.BadRequest as e:
raise exception.InvalidInput(reason=unicode(e))
raise exception.InvalidInput(reason=e)
@translate_volume_exception
def delete(self, context, volume_id):