More robust picking up JSON error responses. · ideko/google-api-python-client@20b54fb · GitHub
Skip to content

Commit 20b54fb

Browse files
committed
More robust picking up JSON error responses.
Fixes issue googleapis#169. Another CL towards fixing 169, by making sure we parse the JSON error response in more cases. Reviewed in http://codereview.appspot.com/6447045/.
1 parent 3fb9367 commit 20b54fb

4 files changed

Lines changed: 36 additions & 34 deletions

File tree

‎apiclient/errors.py‎

Lines changed: 6 additions & 8 deletions

‎tests/test_errors.py‎

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@
4545
}
4646
"""
4747

48-
def fake_response(data, headers):
49-
return httplib2.Response(headers), data
48+
def fake_response(data, headers, reason='Ok'):
49+
response = httplib2.Response(headers)
50+
response.reason = reason
51+
return response, data
5052

5153

5254
class Error(unittest.TestCase):
@@ -55,33 +57,37 @@ class Error(unittest.TestCase):
5557
def test_json_body(self):
5658
"""Test a nicely formed, expected error response."""
5759
resp, content = fake_response(JSON_ERROR_CONTENT,
58-
{'status':'400', 'content-type': 'application/json'})
59-
error = HttpError(resp, content)
60-
self.assertEqual(str(error), '<HttpError 400 "country is required">')
60+
{'status':'400', 'content-type': 'application/json'},
61+
reason='Failed')
62+
error = HttpError(resp, content, 'http://example.org')
63+
self.assertEqual(str(error), '<HttpError 400 when requesting http://example.org returned "country is required">')
6164

6265
def test_bad_json_body(self):
6366
"""Test handling of bodies with invalid json."""
6467
resp, content = fake_response('{',
65-
{'status':'400', 'content-type': 'application/json'})
68+
{ 'status':'400', 'content-type': 'application/json'},
69+
reason='Failed')
6670
error = HttpError(resp, content)
67-
self.assertEqual(str(error), '<HttpError 400 "{">')
71+
self.assertEqual(str(error), '<HttpError 400 "Failed">')
6872

6973
def test_with_uri(self):
7074
"""Test handling of passing in the request uri."""
7175
resp, content = fake_response('{',
72-
{'status':'400', 'content-type': 'application/json'})
76+
{'status':'400', 'content-type': 'application/json'},
77+
reason='Failure')
7378
error = HttpError(resp, content, 'http://example.org')
74-
self.assertEqual(str(error), '<HttpError 400 when requesting http://example.org returned "{">')
79+
self.assertEqual(str(error), '<HttpError 400 when requesting http://example.org returned "Failure">')
7580

7681
def test_missing_message_json_body(self):
7782
"""Test handling of bodies with missing expected 'message' element."""
7883
resp, content = fake_response('{}',
79-
{'status':'400', 'content-type': 'application/json'})
84+
{'status':'400', 'content-type': 'application/json'},
85+
reason='Failed')
8086
error = HttpError(resp, content)
81-
self.assertEqual(str(error), '<HttpError 400 "{}">')
87+
self.assertEqual(str(error), '<HttpError 400 "Failed">')
8288

8389
def test_non_json(self):
8490
"""Test handling of non-JSON bodies"""
85-
resp, content = fake_response('NOT OK', {'status':'400'})
91+
resp, content = fake_response('}NOT OK', {'status':'400'})
8692
error = HttpError(resp, content)
8793
self.assertEqual(str(error), '<HttpError 400 "Ok">')

‎tests/test_http.py‎

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ def test_media_io_base_download_handle_4xx(self):
354354

355355

356356
RESPONSE = """HTTP/1.1 200 OK
357-
Content-Type application/json
357+
Content-Type: application/json
358358
Content-Length: 14
359359
ETag: "etag/pony"\r\n\r\n{"answer": 42}"""
360360

@@ -365,7 +365,7 @@ def test_media_io_base_download_handle_4xx(self):
365365
Content-ID: <randomness+1>
366366
367367
HTTP/1.1 200 OK
368-
Content-Type application/json
368+
Content-Type: application/json
369369
Content-Length: 14
370370
ETag: "etag/pony"\r\n\r\n{"foo": 42}
371371
@@ -375,7 +375,7 @@ def test_media_io_base_download_handle_4xx(self):
375375
Content-ID: <randomness+2>
376376
377377
HTTP/1.1 200 OK
378-
Content-Type application/json
378+
Content-Type: application/json
379379
Content-Length: 14
380380
ETag: "etag/sheep"\r\n\r\n{"baz": "qux"}
381381
--batch_foobarbaz--"""
@@ -387,7 +387,7 @@ def test_media_io_base_download_handle_4xx(self):
387387
Content-ID: <randomness+1>
388388
389389
HTTP/1.1 200 OK
390-
Content-Type application/json
390+
Content-Type: application/json
391391
Content-Length: 14
392392
ETag: "etag/pony"\r\n\r\n{"foo": 42}
393393
@@ -397,11 +397,9 @@ def test_media_io_base_download_handle_4xx(self):
397397
Content-ID: <randomness+2>
398398
399399
HTTP/1.1 403 Access Not Configured
400-
Content-Type application/json
401-
Content-Length: 14
402-
ETag: "etag/sheep"\r\n\r\nContent-Length: 245
403-
404-
{
400+
Content-Type: application/json
401+
Content-Length: 245
402+
ETag: "etag/sheep"\r\n\r\n{
405403
"error": {
406404
"errors": [
407405
{
@@ -425,7 +423,7 @@ def test_media_io_base_download_handle_4xx(self):
425423
Content-ID: <randomness+1>
426424
427425
HTTP/1.1 401 Authorization Required
428-
Content-Type application/json
426+
Content-Type: application/json
429427
Content-Length: 14
430428
ETag: "etag/pony"\r\n\r\n{"error": {"message":
431429
"Authorizaton failed."}}
@@ -436,7 +434,7 @@ def test_media_io_base_download_handle_4xx(self):
436434
Content-ID: <randomness+2>
437435
438436
HTTP/1.1 200 OK
439-
Content-Type application/json
437+
Content-Type: application/json
440438
Content-Length: 14
441439
ETag: "etag/sheep"\r\n\r\n{"baz": "qux"}
442440
--batch_foobarbaz--"""
@@ -448,7 +446,7 @@ def test_media_io_base_download_handle_4xx(self):
448446
Content-ID: <randomness+1>
449447
450448
HTTP/1.1 200 OK
451-
Content-Type application/json
449+
Content-Type: application/json
452450
Content-Length: 14
453451
ETag: "etag/pony"\r\n\r\n{"foo": 42}
454452
--batch_foobarbaz--"""
@@ -708,7 +706,7 @@ def test_execute_global_callback(self):
708706
self.assertEqual({'foo': 42}, callbacks.responses['1'])
709707
self.assertEqual({'baz': 'qux'}, callbacks.responses['2'])
710708

711-
def test_execute_http_error(self):
709+
def test_execute_batch_http_error(self):
712710
callbacks = Callbacks()
713711
batch = BatchHttpRequest(callback=callbacks.f)
714712

‎tests/test_json_model.py‎

Lines changed: 1 addition & 1 deletion

0 commit comments

Comments
 (0)