diff options
author | Jenkins <jenkins@review.openstack.org> | 2016-10-05 00:34:23 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2016-10-05 00:34:23 +0000 |
commit | fd45db19b6faf11443b893f941f936bd4652e76b (patch) | |
tree | 300469f2990385b1c8334f5c3229b80bc71f2b90 | |
parent | 5bdee97f4843de36669e25aa27874c93451fe05a (diff) | |
parent | 70c35e6e3d2aed9f37d5101dafd22c5905ec8583 (diff) | |
download | python-novaclient-stable/mitaka.tar.gz |
Merge "Handle error response for webob>=1.6.0" into stable/mitakamitaka-eol3.3.3stable/mitaka
-rw-r--r-- | novaclient/exceptions.py | 18 | ||||
-rw-r--r-- | novaclient/tests/unit/test_exceptions.py | 48 |
2 files changed, 63 insertions, 3 deletions
diff --git a/novaclient/exceptions.py b/novaclient/exceptions.py index c502e964..31dd4871 100644 --- a/novaclient/exceptions.py +++ b/novaclient/exceptions.py @@ -294,9 +294,21 @@ def from_response(response, body, url, method=None): details = "n/a" if hasattr(body, 'keys'): - error = body[list(body)[0]] - message = error.get('message') - details = error.get('details') + # NOTE(mriedem): WebOb<1.6.0 will return a nested dict structure + # where the error keys to the message/details/code. WebOb>=1.6.0 + # returns just a response body as a single dict, not nested, + # so we have to handle both cases (since we can't trust what we're + # given with content_type: application/json either way. + if 'message' in body: + # WebOb 1.6.0 case + message = body.get('message') + details = body.get('details') + else: + # WebOb<1.6.0 where we assume there is a single error message + # key to the body that has the message and details. + error = body[list(body)[0]] + message = error.get('message') + details = error.get('details') kwargs['message'] = message kwargs['details'] = details diff --git a/novaclient/tests/unit/test_exceptions.py b/novaclient/tests/unit/test_exceptions.py new file mode 100644 index 00000000..34ce11d1 --- /dev/null +++ b/novaclient/tests/unit/test_exceptions.py @@ -0,0 +1,48 @@ +# Copyright 2016 IBM Corp. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from novaclient import exceptions +from novaclient.tests.unit import utils as test_utils + + +class ExceptionsTestCase(test_utils.TestCase): + + def _test_from_response(self, body, expected_message): + data = { + 'status_code': 404, + 'headers': { + 'content-type': 'application/json', + 'x-openstack-request-id': ( + 'req-d9df03b0-4150-4b53-8157-7560ccf39f75'), + } + } + response = test_utils.TestResponse(data) + fake_url = 'http://localhost:8774/v2.1/fake/flavors/test' + error = exceptions.from_response(response, body, fake_url, 'GET') + self.assertIsInstance(error, exceptions.NotFound) + self.assertEqual(expected_message, error.message) + + def test_from_response_webob_pre_1_6_0(self): + # Tests error responses before webob 1.6.0 where the error details + # are nested in the response body. + message = "Flavor test could not be found." + self._test_from_response( + {"itemNotFound": {"message": message, "code": 404}}, + message) + + def test_from_response_webob_post_1_6_0(self): + # Tests error responses from webob 1.6.0 where the error details + # are in the response body. + message = "Flavor test could not be found." + self._test_from_response({"message": message, "code": 404}, message) |