From 4662a9f2be83432aafffd33a2ff8040d726a7d77 Mon Sep 17 00:00:00 2001 From: tengqm Date: Tue, 31 Jan 2017 01:56:16 -0500 Subject: [PATCH] Fix exception parsing error The JSON body from a HTTP exception may contain non-dict values. Previous attempt to fix exception parsing is failing this case. This patch fixes it. Closes-Bug: #1660531 Change-Id: I560439167cf6384ef17ce429d663279502bf9b18 --- openstack/exceptions.py | 3 ++- openstack/tests/unit/test_session.py | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/openstack/exceptions.py b/openstack/exceptions.py index 9fa8c87f..069f020d 100644 --- a/openstack/exceptions.py +++ b/openstack/exceptions.py @@ -125,7 +125,8 @@ def from_exception(exc): content_type = resp.headers.get('content-type', '') if resp_body and 'application/json' in content_type: # Iterate over the nested objects to retrieve "message" attribute. - messages = [obj.get('message') for obj in resp.json().values()] + messages = [obj.get('message') for obj in resp.json().values() + if isinstance(obj, dict)] # Join all of the messages together nicely and filter out any objects # that don't have a "message" attr. details = '\n'.join(msg for msg in messages if msg) diff --git a/openstack/tests/unit/test_session.py b/openstack/tests/unit/test_session.py index a3bdb74c..528fe507 100644 --- a/openstack/tests/unit/test_session.py +++ b/openstack/tests/unit/test_session.py @@ -137,6 +137,27 @@ class TestSession(testtools.TestCase): self.assertIn('OverLimit413...', os_exc.details) self.assertIn('OverLimit Retry...', os_exc.details) + def test_map_exceptions_http_exception_handle_json_1(self): + # A test for json containing non-dict values + mock_resp = mock.Mock() + mock_resp.status_code = 404 + mock_resp.json.return_value = { + "code": 404, + "error": { + "message": "resource not found", + }, + } + mock_resp.headers = { + "content-type": "application/json" + } + ksa_exc = _exceptions.HttpError(message="test", http_status=404, + response=mock_resp) + func = mock.Mock(side_effect=ksa_exc) + + os_exc = self._assert_map_exceptions( + exceptions.HttpException, ksa_exc, func) + self.assertIn('not found', os_exc.details) + def test_map_exceptions_notfound_exception_handle_html(self): mock_resp = mock.Mock() mock_resp.status_code = 404