Skip to content
This repository has been archived by the owner on Dec 11, 2023. It is now read-only.

Commit

Permalink
Merge pull request #122 from librato/bugfix/rate_limit_error_parsing
Browse files Browse the repository at this point in the history
Fix issue with parsing 'error' key vs 'errors' key from API
  • Loading branch information
jderrett committed Jul 5, 2016
2 parents b8e241e + ef625ff commit 133d5b8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 18 deletions.
47 changes: 29 additions & 18 deletions librato/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,30 +63,41 @@ def error_message(self):
# }
# }
#
#
# Rate limiting example:
# {
# u'request_time': 1467306906,
# u'error': u'You have hit the API limit for measurements
# [measure:raw_rate]. Contact: [email protected] to adjust this limit.'
# }
def _parse_error_message(self):
if isinstance(self.error_payload, str):
# Payload is just a string
return self.error_payload
elif isinstance(self.error_payload, dict):
payload = self.error_payload['errors']
messages = []
for key in payload:
error_list = payload[key]
if isinstance(error_list, str):
# The error message is a scalar string, just tack it on
msg = "%s: %s" % (key, error_list)
messages.append(msg)
elif isinstance(error_list, list):
for error_message in error_list:
msg = "%s: %s" % (key, error_message)
messages.append(msg)
elif isinstance(error_list, dict):
for k in error_list:
# e.g. "params: measure_time: "
msg = "%s: %s: " % (key, k)
msg += self._flatten_error_message(error_list[k])
# The API could return 'errors' or just 'error' with a flat message
if 'error' in self.error_payload:
return self.error_payload['error']
else:
payload = self.error_payload['errors']
messages = []
for key in payload:
error_list = payload[key]
if isinstance(error_list, str):
# The error message is a scalar string, just tack it on
msg = "%s: %s" % (key, error_list)
messages.append(msg)
return ", ".join(messages)
elif isinstance(error_list, list):
for error_message in error_list:
msg = "%s: %s" % (key, error_message)
messages.append(msg)
elif isinstance(error_list, dict):
for k in error_list:
# e.g. "params: measure_time: "
msg = "%s: %s: " % (key, k)
msg += self._flatten_error_message(error_list[k])
messages.append(msg)
return ", ".join(messages)

def _flatten_error_message(self, error_msg):
if isinstance(error_msg, str):
Expand Down
9 changes: 9 additions & 0 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ def test_error_message(self):
ex = exceptions.ClientError(400, {"errors": {"request": ["Not found"]}})
self.assertEqual("[400] request: Not found", ex.error_message())

def test_error_vs_errors(self):
msg = "You have hit the rate limit, etc"
# The API actually returns 'errors' in most cases, but for rate
# limiting we get 'error' (singular)
error_resp = {'request_time': 1467306906, 'error': msg}
ex = exceptions.ClientError(403, error_resp)
parsed_msg = ex._parse_error_message()
self.assertEqual(msg, parsed_msg)


if __name__ == '__main__':
unittest.main()

0 comments on commit 133d5b8

Please sign in to comment.