Skip to content
Permalink
Browse files
docs: Change error parsing to check for 'message' (#1083)
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 #1082 馃
  • Loading branch information
mm326 committed Nov 8, 2020
1 parent 8430fac commit a341c5a5e31ba16da109658127b58cb7e5dbeedd
Showing with 38 additions and 6 deletions.
  1. +4 鈭1 docs/start.md
  2. +3 鈭4 googleapiclient/errors.py
  3. +29 鈭0 tests/test_errors.py
  4. +2 鈭1 tests/test_http.py
@@ -94,7 +94,10 @@ request = collection.list(cents=5)
Creating a request does not actually call the API. To execute the request and get a response, call the `execute()` function:

```python
response = request.execute()
try:
response = request.execute()
except HttpError as e:
print('Error response status code : {0}, reason : {1}'.format(e.resp.status, e.error_details))
```

Alternatively, you can combine previous steps on a single line:
@@ -51,10 +51,9 @@ def _get_reason(self):
data = json.loads(self.content.decode("utf-8"))
if isinstance(data, dict):
reason = data["error"]["message"]
if "details" in data["error"]:
self.error_details = data["error"]["details"]
elif "detail" in data["error"]:
self.error_details = data["error"]["detail"]
error_detail_keyword = next((kw for kw in ["detail", "details", "message"] if kw in data["error"]), "")
if error_detail_keyword:
self.error_details = data["error"][error_detail_keyword]
elif isinstance(data, list) and len(data) > 0:
first_error = data[0]
reason = first_error["error"]["message"]
@@ -47,6 +47,24 @@
}
"""

JSON_ERROR_CONTENT_NO_DETAIL = b"""
{
"error": {
"errors": [
{
"domain": "global",
"reason": "required",
"message": "country is required",
"locationType": "parameter",
"location": "country"
}
],
"code": 400,
"message": "country is required"
}
}
"""


def fake_response(data, headers, reason="Ok"):
response = httplib2.Response(headers)
@@ -112,3 +130,14 @@ def test_missing_reason(self):
resp, content = fake_response(b"}NOT OK", {"status": "400"}, reason=None)
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 "">')

def test_error_detail_for_missing_message_in_error(self):
"""Test handling of data with missing 'details' or 'detail' element."""
resp, content = fake_response(
JSON_ERROR_CONTENT_NO_DETAIL,
{"status": "400", "content-type": "application/json"},
reason="Failed",
)
error = HttpError(resp, content)
self.assertEqual(str(error), '<HttpError 400 when requesting None returned "country is required". Details: "country is required">')
self.assertEqual(error.error_details, 'country is required')
@@ -1567,7 +1567,8 @@ def test_execute_batch_http_error(self):
expected = (
"<HttpError 403 when requesting "
"https://www.googleapis.com/someapi/v1/collection/?foo=bar returned "
'"Access Not Configured">'
'"Access Not Configured". '
'Details: "Access Not Configured">'
)
self.assertEqual(expected, str(callbacks.exceptions["2"]))

0 comments on commit a341c5a

Please sign in to comment.