Decode exception parameters to expand exception message properly
If a multibyte string without unicode prefix 'u' is passed to NeutronException in python 2, string subsitution will fail. In python 2, multibyte string without 'u' prefix is encoded into bytes. As a result a string substitution in NeutronException.__init__ will fail. Change-Id: I1aa08b69fe119087a7a49fda768a24f85f0e7c76 Closes-Bug: #1235228
This commit is contained in:

committed by
Akihiro Motoki

parent
f1ae9b7cb4
commit
266e6c3c3c
@@ -13,6 +13,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from oslo_utils import encodeutils
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from neutronclient._i18n import _
|
from neutronclient._i18n import _
|
||||||
@@ -31,6 +32,14 @@ Exceptions are classified into three categories:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# NOTE: This method is defined here to avoid
|
||||||
|
# an import loop between common.utils and this module.
|
||||||
|
def _safe_decode_dict(kwargs):
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
kwargs[k] = encodeutils.safe_decode(v)
|
||||||
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
@six.python_2_unicode_compatible
|
@six.python_2_unicode_compatible
|
||||||
class NeutronException(Exception):
|
class NeutronException(Exception):
|
||||||
"""Base Neutron Exception.
|
"""Base Neutron Exception.
|
||||||
@@ -45,7 +54,7 @@ class NeutronException(Exception):
|
|||||||
if message:
|
if message:
|
||||||
self.message = message
|
self.message = message
|
||||||
try:
|
try:
|
||||||
self._error_string = self.message % kwargs
|
self._error_string = self.message % _safe_decode_dict(kwargs)
|
||||||
except Exception:
|
except Exception:
|
||||||
# at least get the core message out if something happened
|
# at least get the core message out if something happened
|
||||||
self._error_string = self.message
|
self._error_string = self.message
|
||||||
|
@@ -13,6 +13,8 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import fixtures
|
import fixtures
|
||||||
|
from oslo_utils import encodeutils
|
||||||
|
import six
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from neutronclient.common import exceptions
|
from neutronclient.common import exceptions
|
||||||
@@ -34,3 +36,13 @@ class TestExceptions(testtools.TestCase):
|
|||||||
print(e)
|
print(e)
|
||||||
self.assertEqual('Exception with %s' % multibyte_unicode_string,
|
self.assertEqual('Exception with %s' % multibyte_unicode_string,
|
||||||
fixture.getDetails().get('stdout').as_text())
|
fixture.getDetails().get('stdout').as_text())
|
||||||
|
|
||||||
|
def test_exception_message_with_encoded_unicode(self):
|
||||||
|
class TestException(exceptions.NeutronException):
|
||||||
|
message = _('Exception with %(reason)s')
|
||||||
|
|
||||||
|
multibyte_string = u'\uff21\uff22\uff23'
|
||||||
|
multibyte_binary = encodeutils.safe_encode(multibyte_string)
|
||||||
|
e = TestException(reason=multibyte_binary)
|
||||||
|
self.assertEqual('Exception with %s' % multibyte_string,
|
||||||
|
six.text_type(e))
|
||||||
|
Reference in New Issue
Block a user