Skip to content

Commit e6a1da3

Browse files
authored
fix: Improve support for error_details (#1126)
Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: - [x] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-api-python-client/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea - [x] Ensure the tests and linter pass - [x] Code coverage does not decrease (if any source code was changed) - [x] Appropriate docs were updated (if necessary) Fixes #990 🦕
1 parent 8325d24 commit e6a1da3

File tree

2 files changed

+12
-6
lines changed

2 files changed

+12
-6
lines changed

googleapiclient/errors.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ def _get_reason(self):
4848
"""Calculate the reason for the error from the response content."""
4949
reason = self.resp.reason
5050
try:
51-
data = json.loads(self.content.decode("utf-8"))
51+
try:
52+
data = json.loads(self.content.decode("utf-8"))
53+
except json.JSONDecodeError:
54+
# In case it is not json
55+
data = self.content.decode("utf-8")
5256
if isinstance(data, dict):
5357
reason = data["error"]["message"]
5458
error_detail_keyword = next((kw for kw in ["detail", "details", "message"] if kw in data["error"]), "")
@@ -59,6 +63,8 @@ def _get_reason(self):
5963
reason = first_error["error"]["message"]
6064
if "details" in first_error["error"]:
6165
self.error_details = first_error["error"]["details"]
66+
else:
67+
self.error_details = data
6268
except (ValueError, KeyError, TypeError):
6369
pass
6470
if reason is None:

tests/test_errors.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def test_bad_json_body(self):
9494
b"{", {"status": "400", "content-type": "application/json"}, reason="Failed"
9595
)
9696
error = HttpError(resp, content)
97-
self.assertEqual(str(error), '<HttpError 400 "Failed">')
97+
self.assertEqual(str(error), '<HttpError 400 when requesting None returned "Failed". Details: "{">')
9898

9999
def test_with_uri(self):
100100
"""Test handling of passing in the request uri."""
@@ -106,7 +106,7 @@ def test_with_uri(self):
106106
error = HttpError(resp, content, uri="http://example.org")
107107
self.assertEqual(
108108
str(error),
109-
'<HttpError 400 when requesting http://example.org returned "Failure">',
109+
'<HttpError 400 when requesting http://example.org returned "Failure". Details: "{">',
110110
)
111111

112112
def test_missing_message_json_body(self):
@@ -121,15 +121,15 @@ def test_missing_message_json_body(self):
121121

122122
def test_non_json(self):
123123
"""Test handling of non-JSON bodies"""
124-
resp, content = fake_response(b"}NOT OK", {"status": "400"})
124+
resp, content = fake_response(b"Invalid request", {"status": "400"})
125125
error = HttpError(resp, content)
126-
self.assertEqual(str(error), '<HttpError 400 "Ok">')
126+
self.assertEqual(str(error), '<HttpError 400 when requesting None returned "Ok". Details: "Invalid request">')
127127

128128
def test_missing_reason(self):
129129
"""Test an empty dict with a missing resp.reason."""
130130
resp, content = fake_response(b"}NOT OK", {"status": "400"}, reason=None)
131131
error = HttpError(resp, content)
132-
self.assertEqual(str(error), '<HttpError 400 "">')
132+
self.assertEqual(str(error), '<HttpError 400 when requesting None returned "". Details: "}NOT OK">')
133133

134134
def test_error_detail_for_missing_message_in_error(self):
135135
"""Test handling of data with missing 'details' or 'detail' element."""

0 commit comments

Comments
 (0)