Fix crash on Service catalog empty 403 response

Added handling of message body received as bytes ("application/json")
to avoid "TypeError: the JSON object must be str, not 'bytes'"

Change-Id: I007b33e1b9f210ede2df5d1e2aa32535222d5d67
Task:24818
Story: 2003533
Signed-off-by: Boris Pilka <boris.pilka@x-works.io>
This commit is contained in:
Boris Pilka 2018-08-23 16:51:58 +02:00
parent c026a13e15
commit 125a9a5587
2 changed files with 41 additions and 24 deletions

View File

@ -39,32 +39,42 @@ API_VERSION = '/v1'
DEFAULT_API_VERSION = 'latest'
def _extract_error_json(body):
"""Return error_message from the HTTP response body."""
def _extract_error_json_text(body_json):
error_json = {}
try:
body_json = json.loads(body)
if 'error_message' in body_json:
raw_msg = body_json['error_message']
error_json = json.loads(raw_msg)
elif 'error' in body_json:
error_body = body_json['error']
error_json = {'faultstring': error_body['title'],
'debuginfo': error_body['message']}
else:
error_body = body_json['errors'][0]
error_json = {'faultstring': error_body['title']}
if 'detail' in error_body:
error_json['debuginfo'] = error_body['detail']
elif 'description' in error_body:
error_json['debuginfo'] = error_body['description']
except ValueError:
return {}
if 'error_message' in body_json:
raw_msg = body_json['error_message']
error_json = json.loads(raw_msg)
elif 'error' in body_json:
error_body = body_json['error']
error_json = {'faultstring': error_body['title'],
'debuginfo': error_body['message']}
else:
error_body = body_json['errors'][0]
error_json = {'faultstring': error_body['title']}
if 'detail' in error_body:
error_json['debuginfo'] = error_body['detail']
elif 'description' in error_body:
error_json['debuginfo'] = error_body['description']
return error_json
def _extract_error_json(body, resp):
"""Return error_message from the HTTP response body."""
content_type = resp.headers.get("Content-Type", "")
if content_type.startswith("application/json"):
try:
body_json = resp.json()
return _extract_error_json_text(body_json)
except ValueError:
return {}
else:
try:
body_json = json.loads(body)
return _extract_error_json_text(body_json)
except ValueError:
return {}
class HTTPClient(object):
def __init__(self, endpoint, api_version=DEFAULT_API_VERSION, **kwargs):
@ -200,7 +210,7 @@ class HTTPClient(object):
if 400 <= resp.status < 600:
LOG.warning("Request returned failure status.")
error_json = _extract_error_json(body_str)
error_json = _extract_error_json(body_str, resp)
raise exceptions.from_response(
resp, error_json.get('faultstring'),
error_json.get('debuginfo'), method, url)
@ -346,7 +356,7 @@ class SessionClient(adapter.LegacyJsonAdapter):
raise_exc=False, **kwargs)
if 400 <= resp.status_code < 600:
error_json = _extract_error_json(resp.content)
error_json = _extract_error_json(resp.content, resp)
raise exceptions.from_response(
resp, error_json.get('faultstring'),
error_json.get('debuginfo'), method, url)

View File

@ -15,6 +15,7 @@
import copy
import datetime
import json as jsonlib
import os
import sys
@ -179,6 +180,12 @@ class FakeSessionResponse(object):
self.content = content
self.status_code = status_code
def json(self):
if self.content is not None:
return jsonlib.loads(self.content)
else:
return {}
class FakeSession(object):