else:
LOG.exception(_('%s failed'), action)
e = translate(e, language)
- # following structure is expected by python-neutronclient
- err_data = {'type': e.__class__.__name__,
- 'message': e, 'detail': ''}
- body = serializer.serialize({'NeutronError': err_data})
+ body = serializer.serialize(
+ {'NeutronError': get_exception_data(e)})
kwargs = {'body': body, 'content_type': content_type}
raise mapped_exc(**kwargs)
except webob.exc.HTTPException as e:
type_, value, tb = sys.exc_info()
LOG.exception(_('%s failed'), action)
translate(e, language)
- value.body = serializer.serialize({'NeutronError': e})
+ value.body = serializer.serialize(
+ {'NeutronError': get_exception_data(e)})
value.content_type = content_type
six.reraise(type_, value, tb)
except NotImplementedError as e:
# because a plugin does not implement a feature,
# returning 500 is definitely confusing.
body = serializer.serialize(
- {'NotImplementedError': e.message})
+ {'NotImplementedError': get_exception_data(e)})
kwargs = {'body': body, 'content_type': content_type}
raise webob.exc.HTTPNotImplemented(**kwargs)
except Exception:
msg = _('Request Failed: internal server error while '
'processing your request.')
msg = translate(msg, language)
- body = serializer.serialize({'NeutronError': msg})
+ body = serializer.serialize(
+ {'NeutronError': get_exception_data(
+ webob.exc.HTTPInternalServerError(msg))})
kwargs = {'body': body, 'content_type': content_type}
raise webob.exc.HTTPInternalServerError(**kwargs)
return resource
+def get_exception_data(e):
+ """Extract the information about an exception.
+
+ Neutron client for the v2 API expects exceptions to have 'type', 'message'
+ and 'detail' attributes.This information is extracted and converted into a
+ dictionary.
+
+ :param e: the exception to be reraised
+ :returns: a structured dict with the exception data
+ """
+ err_data = {'type': e.__class__.__name__,
+ 'message': e, 'detail': ''}
+ return err_data
+
+
def translate(translatable, locale):
"""Translates the object to the given locale.
class ResourceTestCase(base.BaseTestCase):
+ @staticmethod
+ def _get_deserializer(req_format):
+ if req_format == 'json':
+ return wsgi.JSONDeserializer()
+ else:
+ return wsgi.XMLDeserializer()
+
def test_unmapped_neutron_error_with_json(self):
msg = u'\u7f51\u7edc'
self.assertIn(msg_translation,
str(wsgi.JSONDeserializer().deserialize(res.body)))
- def test_http_error(self):
+ @staticmethod
+ def _make_request_with_side_effect(side_effect, req_format=None):
controller = mock.MagicMock()
- controller.test.side_effect = exc.HTTPGatewayTimeout()
+ controller.test.side_effect = side_effect
resource = webtest.TestApp(wsgi_resource.Resource(controller))
- environ = {'wsgiorg.routing_args': (None, {'action': 'test'})}
+ routing_args = {'action': 'test'}
+ if req_format:
+ routing_args.update({'format': req_format})
+ environ = {'wsgiorg.routing_args': (None, routing_args)}
res = resource.get('', extra_environ=environ, expect_errors=True)
- self.assertEqual(res.status_int, exc.HTTPGatewayTimeout.code)
+ return res
- def test_unhandled_error_with_json(self):
+ def test_http_error(self):
+ res = self._make_request_with_side_effect(exc.HTTPGatewayTimeout())
+
+ # verify that the exception structure is the one expected
+ # by the python-neutronclient
+ self.assertEqual(exc.HTTPGatewayTimeout().explanation,
+ res.json['NeutronError']['message'])
+ self.assertEqual('HTTPGatewayTimeout',
+ res.json['NeutronError']['type'])
+ self.assertEqual('', res.json['NeutronError']['detail'])
+ self.assertEqual(exc.HTTPGatewayTimeout.code, res.status_int)
+
+ def _test_unhandled_error(self, req_format='json'):
expected_res = {'body': {'NeutronError':
- _('Request Failed: internal server error '
- 'while processing your request.')}}
- controller = mock.MagicMock()
- controller.test.side_effect = Exception()
+ {'detail': '',
+ 'message': _(
+ 'Request Failed: internal server '
+ 'error while processing your request.'),
+ 'type': 'HTTPInternalServerError'}}}
+ res = self._make_request_with_side_effect(side_effect=Exception(),
+ req_format=req_format)
+ self.assertEqual(exc.HTTPInternalServerError.code,
+ res.status_int)
+ self.assertEqual(expected_res,
+ self._get_deserializer(
+ req_format).deserialize(res.body))
- resource = webtest.TestApp(wsgi_resource.Resource(controller))
-
- environ = {'wsgiorg.routing_args': (None, {'action': 'test',
- 'format': 'json'})}
- res = resource.get('', extra_environ=environ, expect_errors=True)
- self.assertEqual(res.status_int, exc.HTTPInternalServerError.code)
- self.assertEqual(wsgi.JSONDeserializer().deserialize(res.body),
- expected_res)
+ def test_unhandled_error_with_json(self):
+ self._test_unhandled_error()
def test_unhandled_error_with_xml(self):
- expected_res = {'body': {'NeutronError':
- _('Request Failed: internal server error '
- 'while processing your request.')}}
- controller = mock.MagicMock()
- controller.test.side_effect = Exception()
+ self._test_unhandled_error(req_format='xml')
- resource = webtest.TestApp(wsgi_resource.Resource(controller))
-
- environ = {'wsgiorg.routing_args': (None, {'action': 'test',
- 'format': 'xml'})}
- res = resource.get('', extra_environ=environ, expect_errors=True)
- self.assertEqual(res.status_int, exc.HTTPInternalServerError.code)
- self.assertEqual(wsgi.XMLDeserializer().deserialize(res.body),
- expected_res)
+ def _test_not_implemented_error(self, req_format='json'):
+ expected_res = {'body': {'NeutronError':
+ {'detail': '',
+ 'message': _(
+ 'The server has either erred or is '
+ 'incapable of performing the requested '
+ 'operation.'),
+ 'type': 'HTTPNotImplemented'}}}
+
+ res = self._make_request_with_side_effect(exc.HTTPNotImplemented(),
+ req_format=req_format)
+ self.assertEqual(exc.HTTPNotImplemented.code, res.status_int)
+ self.assertEqual(expected_res,
+ self._get_deserializer(
+ req_format).deserialize(res.body))
+
+ def test_not_implemented_error_with_json(self):
+ self._test_not_implemented_error()
+
+ def test_not_implemented_error_with_xml(self):
+ self._test_not_implemented_error(req_format='xml')
def test_status_200(self):
controller = mock.MagicMock()