diff --git a/init.php b/init.php index 690a237fc..baeae8d3e 100644 --- a/init.php +++ b/init.php @@ -22,6 +22,7 @@ require(dirname(__FILE__) . '/lib/Error/ApiConnection.php'); require(dirname(__FILE__) . '/lib/Error/Authentication.php'); require(dirname(__FILE__) . '/lib/Error/Card.php'); +require(dirname(__FILE__) . '/lib/Error/Idempotency.php'); require(dirname(__FILE__) . '/lib/Error/InvalidRequest.php'); require(dirname(__FILE__) . '/lib/Error/Permission.php'); require(dirname(__FILE__) . '/lib/Error/RateLimit.php'); diff --git a/lib/ApiRequestor.php b/lib/ApiRequestor.php index 5c13a156a..334d84425 100644 --- a/lib/ApiRequestor.php +++ b/lib/ApiRequestor.php @@ -70,6 +70,7 @@ public function request($method, $url, $params = null, $headers = null) * @param array $resp * * @throws Error\InvalidRequest if the error is caused by the user. + * @throws Error\Idempotency if the error is caused by an idempotency key. * @throws Error\Authentication if the error is caused by a lack of * permissions. * @throws Error\Permission if the error is caused by insufficient @@ -106,6 +107,7 @@ private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $err $msg = isset($errorData['message']) ? $errorData['message'] : null; $param = isset($errorData['param']) ? $errorData['param'] : null; $code = isset($errorData['code']) ? $errorData['code'] : null; + $type = isset($errorData['type']) ? $errorData['type'] : null; switch ($rcode) { case 400: @@ -114,6 +116,9 @@ private static function _specificAPIError($rbody, $rcode, $rheaders, $resp, $err if ($code == 'rate_limit') { return new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders); } + if ($type == 'idempotency_error') { + return new Error\Idempotency($msg, $rcode, $rbody, $resp, $rheaders); + } // intentional fall-through case 404: diff --git a/lib/Error/Idempotency.php b/lib/Error/Idempotency.php new file mode 100644 index 000000000..ea44d12e4 --- /dev/null +++ b/lib/Error/Idempotency.php @@ -0,0 +1,7 @@ +stubRequest( + 'POST', + '/v1/charges', + array(), + null, + false, + array( + 'error' => array( + 'type' => 'idempotency_error', + 'message' => "Keys for idempotent requests can only be used with the same parameters they were first used with. Try using a key other than 'abc' if you meant to execute a different request.", + ), + ), + 400 + ); + + try { + Charge::create(); + $this->fail("Did not raise error"); + } catch (Error\Idempotency $e) { + $this->assertSame(400, $e->getHttpStatus()); + $this->assertTrue(is_array($e->getJsonBody())); + $this->assertSame("Keys for idempotent requests can only be used with the same parameters they were first used with. Try using a key other than 'abc' if you meant to execute a different request.", $e->getMessage()); + } catch (\Exception $e) { + $this->fail("Unexpected exception: " . get_class($e)); + } + } + public function testRaisesAuthenticationErrorOn401() { $this->stubRequest(