Skip to content

Commit

Permalink
Merge pull request #654 from williamdes/fix-idempotency
Browse files Browse the repository at this point in the history
Fix idempotency response should return an Error object
  • Loading branch information
iulian03 authored Nov 12, 2024
2 parents 7aad50d + 39e09c6 commit 32313c5
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 3 deletions.
14 changes: 11 additions & 3 deletions MangoPay/ApiResponses.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
35 changes: 35 additions & 0 deletions MangoPay/Libraries/ApiBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,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
Expand Down
18 changes: 18 additions & 0 deletions tests/Cases/IdempotencyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit 32313c5

Please sign in to comment.