diff --git a/MangoPay/ApiResponses.php b/MangoPay/ApiResponses.php index 1c6440c6..7ebbc3ab 100644 --- a/MangoPay/ApiResponses.php +++ b/MangoPay/ApiResponses.php @@ -16,12 +16,20 @@ class ApiResponses extends Libraries\ApiBase public function Get($idempotencyKey) { $response = $this->GetObject('responses_get', 'MangoPay\Response', $idempotencyKey); - $className = $this->GetObjectForIdempotencyUrl($response->RequestURL); - if (is_null($className) || empty($className) || is_null($response->Resource) || empty($response->Resource)) { + + // Same logic as RestTool::CheckResponseCode + if ($response->StatusCode >= 200 && $response->StatusCode <= 299) { + // Target the class to use from the SDK + $className = $this->GetObjectForIdempotencyUrl($response->RequestURL); + if (is_null($className) || empty($className) || is_null($response->Resource) || empty($response->Resource)) { + return $response; + } + + $response->Resource = $this->CastResponseToEntity($response->Resource, $className); return $response; } - $response->Resource = $this->CastResponseToEntity($response->Resource, $className); + $response->Resource = $this->CastResponseToError($response->Resource); return $response; } } diff --git a/MangoPay/Libraries/ApiBase.php b/MangoPay/Libraries/ApiBase.php index fcf4f766..12752e94 100644 --- a/MangoPay/Libraries/ApiBase.php +++ b/MangoPay/Libraries/ApiBase.php @@ -430,6 +430,41 @@ protected function ExecutePostRequest($methodKey, $entity, $responseClassName, $ return $response; } + /** + * Cast response object to an error object + * @param object $response Object from API response + * @return Error The error + */ + protected function CastResponseToError($response) + { + // This logic is similar to RestTool::CheckResponseCode + $error = new Error(); + + $map = [ + 'Message', + 'Id', + 'Type', + 'Date', + 'Errors', + ]; + + foreach ($map as $val) { + $error->{$val} = property_exists($response, $val) ? $response->{$val} : null; + } + + if (property_exists($response, 'errors')) { + $error->Errors = $response->errors; + } + + if (is_array($error->Errors)) { + foreach ($error->Errors as $key => $val) { + $error->Message .= sprintf(' %s error: %s', $key, $val); + } + } + + return $error; + } + /** * Cast response object to entity object * @param object $response Object from API response diff --git a/tests/Cases/IdempotencyTest.php b/tests/Cases/IdempotencyTest.php index 3adc5ca3..aef84149 100644 --- a/tests/Cases/IdempotencyTest.php +++ b/tests/Cases/IdempotencyTest.php @@ -52,6 +52,24 @@ public function test_DifferentIdempotencyKey_ActIndependentlyAndRetreivable() $this->assertTrue($resp2->Resource->Id == $user2->Id); } + public function test_SameIdempotencyKey_ErrorAndGetBackError() + { + $idempotencyKey = md5(uniqid()); + $user = $this->buildJohn(); + $user->FirstName = null;// Trigger an error: The FirstName field is required + try { + $user1 = $this->_api->Users->Create($user, $idempotencyKey); + } catch (ResponseException $exception) { + // Check it is what we expect + self::assertStringContainsString('The FirstName field is required', $exception->GetErrorDetails()->Errors->FirstName); + } + // Use case: the user lost the above exception and wants to get it back + $response = $this->_api->Responses->Get($idempotencyKey); + self::assertInstanceOf('MangoPay\Response', $response); + self::assertInstanceOf('MangoPay\Libraries\Error', $response->Resource); + self::assertStringContainsString('The FirstName field is required', $response->Resource->Errors->FirstName); + } + public function test_GetIdempotencyKey_PreauthorizationCreate() { $key = md5(uniqid());