Skip to content

Commit 90ffb85

Browse files
bantiniJon Wayne Parrott
authored andcommitted
fix: 458 handle error format (#459)
1 parent b8b68fe commit 90ffb85

File tree

2 files changed

+42
-4
lines changed

2 files changed

+42
-4
lines changed

googleapiclient/http.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def _should_retry_response(resp_status, content):
8989
9090
Args:
9191
resp_status: The response status received.
92-
content: The response content body.
92+
content: The response content body.
9393
9494
Returns:
9595
True if the response should be retried, otherwise False.
@@ -112,7 +112,10 @@ def _should_retry_response(resp_status, content):
112112
# Content is in JSON format.
113113
try:
114114
data = json.loads(content.decode('utf-8'))
115-
reason = data['error']['errors'][0]['reason']
115+
if isinstance(data, dict):
116+
reason = data['error']['errors'][0]['reason']
117+
else:
118+
reason = data[0]['error']['errors']['reason']
116119
except (UnicodeDecodeError, ValueError, KeyError):
117120
LOGGER.warning('Invalid JSON content from response: %s', content)
118121
return False
@@ -510,7 +513,6 @@ class MediaFileUpload(MediaIoBaseUpload):
510513
Construct a MediaFileUpload and pass as the media_body parameter of the
511514
method. For example, if we had a service that allowed uploading images:
512515
513-
514516
media = MediaFileUpload('cow.png', mimetype='image/png',
515517
chunksize=1024*1024, resumable=True)
516518
farm.animals().insert(

tests/test_http.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ def request(self, *args, **kwargs):
128128
ex = TimeoutError()
129129
else:
130130
ex = socket.error()
131-
132131
if self.num_errors == 2:
133132
#first try a broken pipe error (#218)
134133
ex.errno = socket.errno.EPIPE
@@ -739,6 +738,20 @@ def test_media_io_base_download_empty_file(self):
739738
}
740739
}"""
741740

741+
LIST_NOT_CONFIGURED_RESPONSE = """[
742+
"error": {
743+
"errors": [
744+
{
745+
"domain": "usageLimits",
746+
"reason": "accessNotConfigured",
747+
"message": "Access Not Configured"
748+
}
749+
],
750+
"code": 403,
751+
"message": "Access Not Configured"
752+
}
753+
]"""
754+
742755
class Callbacks(object):
743756
def __init__(self):
744757
self.responses = {}
@@ -956,6 +969,29 @@ def test_no_retry_401_fails_fast(self):
956969
request.execute()
957970
request._sleep.assert_not_called()
958971

972+
def test_no_retry_403_list_fails(self):
973+
http = HttpMockSequence([
974+
({'status': '403'}, LIST_NOT_CONFIGURED_RESPONSE),
975+
({'status': '200'}, '{}')
976+
])
977+
model = JsonModel()
978+
uri = u'https://www.googleapis.com/someapi/v1/collection/?foo=bar'
979+
method = u'POST'
980+
request = HttpRequest(
981+
http,
982+
model.response,
983+
uri,
984+
method=method,
985+
body=u'{}',
986+
headers={'content-type': 'application/json'})
987+
988+
request._rand = lambda: 1.0
989+
request._sleep = mock.MagicMock()
990+
991+
with self.assertRaises(HttpError):
992+
request.execute()
993+
request._sleep.assert_not_called()
994+
959995
class TestBatch(unittest.TestCase):
960996

961997
def setUp(self):

0 commit comments

Comments
 (0)