From 7e2622c2fc89611a34c242792f46572545bcdffb Mon Sep 17 00:00:00 2001 From: "Luis A. Garcia" Date: Fri, 16 Aug 2013 16:07:47 +0000 Subject: [PATCH] Enhance exception translation to better handle NeutronExceptions NeutronExceptions have a 'message' class attribute that holds the generic error message template, e.g. "Network %(network)s not found", unfortunately, because the names are the same, it was overshadowing the actual exception instance 'message', e.g. "Network 1 not found", after translation when the exception was serialized to JSON. This patch puts the exception's actual message in a new field called 'msg' and overwrites NeutronException unicode() so that 'msg' is used during serialization and we'll get the correct message on the REST API response. Fixes bug: #1212882 Change-Id: I3965bffb1c2c2eee0af440d1ecd30ccb3bb958d5 --- neutron/api/v2/resource.py | 13 ++++++++----- neutron/common/exceptions.py | 4 ++++ neutron/tests/unit/test_api_v2_resource.py | 6 ++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/neutron/api/v2/resource.py b/neutron/api/v2/resource.py index 529f519ed..0066846aa 100644 --- a/neutron/api/v2/resource.py +++ b/neutron/api/v2/resource.py @@ -147,9 +147,12 @@ def translate(translatable, locale): was not translated """ localize = gettextutils.get_localized_message - if isinstance(translatable, Exception): + if isinstance(translatable, exceptions.NeutronException): + translatable.msg = localize(translatable.msg, locale) + elif isinstance(translatable, webob.exc.HTTPError): + translatable.detail = localize(translatable.detail, locale) + elif isinstance(translatable, Exception): translatable.message = localize(translatable.message, locale) - if isinstance(translatable, webob.exc.HTTPError): - translatable.detail = localize(translatable.detail, locale) - return translatable - return localize(translatable, locale) + else: + return localize(translatable, locale) + return translatable diff --git a/neutron/common/exceptions.py b/neutron/common/exceptions.py index b51f91b77..7b0264733 100644 --- a/neutron/common/exceptions.py +++ b/neutron/common/exceptions.py @@ -34,6 +34,7 @@ class NeutronException(Exception): def __init__(self, **kwargs): try: super(NeutronException, self).__init__(self.message % kwargs) + self.msg = self.message % kwargs except Exception: if _FATAL_EXCEPTION_FORMAT_ERRORS: raise @@ -41,6 +42,9 @@ class NeutronException(Exception): # at least get the core message out if something happened super(NeutronException, self).__init__(self.message) + def __unicode__(self): + return unicode(self.msg) + class BadRequest(NeutronException): message = _('Bad %(resource)s request: %(msg)s') diff --git a/neutron/tests/unit/test_api_v2_resource.py b/neutron/tests/unit/test_api_v2_resource.py index 4444c7576..3ada9cf64 100644 --- a/neutron/tests/unit/test_api_v2_resource.py +++ b/neutron/tests/unit/test_api_v2_resource.py @@ -160,8 +160,7 @@ class ResourceTestCase(base.BaseTestCase): self.assertEqual(wsgi.XMLDeserializer().deserialize(res.body), expected_res) - @mock.patch('neutron.openstack.common.gettextutils.Message.data', - new_callable=mock.PropertyMock) + @mock.patch('neutron.openstack.common.gettextutils.get_localized_message') def test_unmapped_neutron_error_localized(self, mock_translation): gettextutils.install('blaa', lazy=True) msg_translation = 'Translated error' @@ -223,8 +222,7 @@ class ResourceTestCase(base.BaseTestCase): self.assertEqual(wsgi.XMLDeserializer().deserialize(res.body), expected_res) - @mock.patch('neutron.openstack.common.gettextutils.Message.data', - new_callable=mock.PropertyMock) + @mock.patch('neutron.openstack.common.gettextutils.get_localized_message') def test_mapped_neutron_error_localized(self, mock_translation): gettextutils.install('blaa', lazy=True) msg_translation = 'Translated error' -- 2.45.2