diff --git a/neutron/api/v2/resource.py b/neutron/api/v2/resource.py index 0066846aab..8a69b55577 100644 --- a/neutron/api/v2/resource.py +++ b/neutron/api/v2/resource.py @@ -86,7 +86,10 @@ def Resource(controller, faults=None, deserializers=None, serializers=None): netaddr.AddrFormatError) as e: LOG.exception(_('%s failed'), action) e = translate(e, language) - body = serializer.serialize({'NeutronError': e}) + # following structure is expected by python-neutronclient + err_data = {'type': e.__class__.__name__, + 'message': e, 'detail': ''} + body = serializer.serialize({'NeutronError': err_data}) kwargs = {'body': body, 'content_type': content_type} for fault in faults: if isinstance(e, fault): diff --git a/neutron/tests/unit/test_api_v2.py b/neutron/tests/unit/test_api_v2.py index 012822e0d6..3268bbac18 100644 --- a/neutron/tests/unit/test_api_v2.py +++ b/neutron/tests/unit/test_api_v2.py @@ -1315,7 +1315,7 @@ class QuotaTest(APIv2TestBase): instance.get_networks_count.assert_called_with(mock.ANY, filters=mock.ANY) self.assertIn("Quota exceeded for resources", - res.json['NeutronError']) + res.json['NeutronError']['message']) def test_create_network_quota_no_counts(self): cfg.CONF.set_override('quota_network', 1, group='QUOTAS') @@ -1332,7 +1332,7 @@ class QuotaTest(APIv2TestBase): instance.get_networks_count.assert_called_with(mock.ANY, filters=mock.ANY) self.assertIn("Quota exceeded for resources", - res.json['NeutronError']) + res.json['NeutronError']['message']) def test_create_network_quota_without_limit(self): cfg.CONF.set_override('quota_network', -1, group='QUOTAS') diff --git a/neutron/tests/unit/test_api_v2_resource.py b/neutron/tests/unit/test_api_v2_resource.py index 3ada9cf646..564a01c4ce 100644 --- a/neutron/tests/unit/test_api_v2_resource.py +++ b/neutron/tests/unit/test_api_v2_resource.py @@ -129,7 +129,11 @@ class ResourceTestCase(base.BaseTestCase): class TestException(q_exc.NeutronException): message = msg - expected_res = {'body': {'NeutronError': msg}} + expected_res = {'body': { + 'NeutronError': { + 'type': 'TestException', + 'message': msg, + 'detail': ''}}} controller = mock.MagicMock() controller.test.side_effect = TestException() @@ -147,7 +151,11 @@ class ResourceTestCase(base.BaseTestCase): class TestException(q_exc.NeutronException): message = msg - expected_res = {'body': {'NeutronError': msg}} + expected_res = {'body': { + 'NeutronError': { + 'type': 'TestException', + 'message': msg, + 'detail': ''}}} controller = mock.MagicMock() controller.test.side_effect = TestException() @@ -187,7 +195,11 @@ class ResourceTestCase(base.BaseTestCase): class TestException(q_exc.NeutronException): message = msg - expected_res = {'body': {'NeutronError': msg}} + expected_res = {'body': { + 'NeutronError': { + 'type': 'TestException', + 'message': msg, + 'detail': ''}}} controller = mock.MagicMock() controller.test.side_effect = TestException() @@ -207,7 +219,11 @@ class ResourceTestCase(base.BaseTestCase): class TestException(q_exc.NeutronException): message = msg - expected_res = {'body': {'NeutronError': msg}} + expected_res = {'body': { + 'NeutronError': { + 'type': 'TestException', + 'message': msg, + 'detail': ''}}} controller = mock.MagicMock() controller.test.side_effect = TestException() diff --git a/neutron/tests/unit/test_db_plugin.py b/neutron/tests/unit/test_db_plugin.py index 9d7da0621e..002f283886 100644 --- a/neutron/tests/unit/test_db_plugin.py +++ b/neutron/tests/unit/test_db_plugin.py @@ -1162,7 +1162,7 @@ fixed_ips=ip_address%%3D%s&fixed_ips=ip_address%%3D%s&fixed_ips=subnet_id%%3D%s res = self._create_port(self.fmt, id) data = self.deserialize(self.fmt, res) msg = str(q_exc.IpAddressGenerationFailure(net_id=id)) - self.assertEqual(data['NeutronError'], msg) + self.assertEqual(data['NeutronError']['message'], msg) self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) def test_update_port_update_ip(self): @@ -2477,7 +2477,7 @@ class TestSubnetsV2(NeutronDbPluginV2TestCase): data = self.deserialize(self.fmt, res) self.assertEqual(res.status_int, webob.exc.HTTPConflict.code) msg = str(q_exc.SubnetInUse(subnet_id=id)) - self.assertEqual(data['NeutronError'], msg) + self.assertEqual(data['NeutronError']['message'], msg) def test_delete_network(self): gateway_ip = '10.0.0.1'