diff --git a/stripe/__init__.py b/stripe/__init__.py index aec51c41b..6920c630d 100644 --- a/stripe/__init__.py +++ b/stripe/__init__.py @@ -43,6 +43,7 @@ PermissionError, RateLimitError, CardError, + IdempotencyError, InvalidRequestError, SignatureVerificationError, StripeError) diff --git a/stripe/api_requestor.py b/stripe/api_requestor.py index 36a2075e0..cf539e203 100644 --- a/stripe/api_requestor.py +++ b/stripe/api_requestor.py @@ -191,9 +191,13 @@ def specific_api_error(self, rbody, rcode, resp, rheaders, error_data): return error.RateLimitError( error_data.get('message'), rbody, rcode, resp, rheaders) elif rcode in [400, 404]: - return error.InvalidRequestError( - error_data.get('message'), error_data.get('param'), - error_data.get('code'), rbody, rcode, resp, rheaders) + if error_data.get('type') == "idempotency_error": + return error.IdempotencyError( + error_data.get('message'), rbody, rcode, resp, rheaders) + else: + return error.InvalidRequestError( + error_data.get('message'), error_data.get('param'), + error_data.get('code'), rbody, rcode, resp, rheaders) elif rcode == 401: return error.AuthenticationError( error_data.get('message'), rbody, rcode, resp, rheaders) diff --git a/stripe/error.py b/stripe/error.py index b33de406b..892df00fe 100644 --- a/stripe/error.py +++ b/stripe/error.py @@ -57,6 +57,10 @@ def __init__(self, message, param, code, http_body=None, self.code = code +class IdempotencyError(StripeError): + pass + + class InvalidRequestError(StripeError): def __init__(self, message, param, code=None, http_body=None, diff --git a/tests/test_api_requestor.py b/tests/test_api_requestor.py index a8e162361..a01b5c521 100644 --- a/tests/test_api_requestor.py +++ b/tests/test_api_requestor.py @@ -391,13 +391,27 @@ def test_fails_without_api_key(self): self.requestor.request, 'get', self.valid_path, {}) - def test_not_found(self): + def test_invalid_request_error_404(self): self.mock_response('{"error": {}}', 404) self.assertRaises(stripe.error.InvalidRequestError, self.requestor.request, 'get', self.valid_path, {}) + def test_invalid_request_error_400(self): + self.mock_response('{"error": {}}', 400) + + self.assertRaises(stripe.error.InvalidRequestError, + self.requestor.request, + 'get', self.valid_path, {}) + + def test_idempotency_error(self): + self.mock_response('{"error": {"type": "idempotency_error"}}', 400) + + self.assertRaises(stripe.error.IdempotencyError, + self.requestor.request, + 'get', self.valid_path, {}) + def test_authentication_error(self): self.mock_response('{"error": {}}', 401)