From 64e05100a2c20c8d1f8e5f9719ee5292c59761c2 Mon Sep 17 00:00:00 2001 From: Orkun Date: Wed, 28 Aug 2024 14:44:44 +0300 Subject: [PATCH 1/3] feat: add retry after policy to api exception This commit solves task inter-860 --- src/Api/FingerprintApi.php | 28 ++++++++++++++++++++++++++++ src/ApiException.php | 11 +++++++++++ template/ApiException.mustache | 11 +++++++++++ template/api.mustache | 16 ++++++++++++++++ 4 files changed, 66 insertions(+) diff --git a/src/Api/FingerprintApi.php b/src/Api/FingerprintApi.php index e2413418..60ae6b72 100644 --- a/src/Api/FingerprintApi.php +++ b/src/Api/FingerprintApi.php @@ -149,6 +149,13 @@ public function getEvent(string $request_id): array break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } } @@ -219,6 +226,13 @@ function ($e) { break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } ); @@ -308,6 +322,13 @@ public function getVisits(string $visitor_id, ?string $request_id = null, ?strin break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } } @@ -383,6 +404,13 @@ function ($e) { break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } ); diff --git a/src/ApiException.php b/src/ApiException.php index a31ebdff..be7536f6 100644 --- a/src/ApiException.php +++ b/src/ApiException.php @@ -44,6 +44,7 @@ class ApiException extends \Exception { protected ResponseInterface $responseObject; protected ModelInterface $errorDetails; + protected ?int $retryAfter = null; public function __construct(?string $message = '', ?int $code = 0) { @@ -72,4 +73,14 @@ public function setErrorDetails(ModelInterface $errorDetails): void { $this->errorDetails = $errorDetails; } + + public function getRetryAfter(): ?int + { + return $this->retryAfter; + } + + public function setRetryAfter(?int $retryAfter): void + { + $this->retryAfter = $retryAfter; + } } diff --git a/template/ApiException.mustache b/template/ApiException.mustache index fe6fd54d..f6a323b7 100644 --- a/template/ApiException.mustache +++ b/template/ApiException.mustache @@ -34,6 +34,7 @@ class ApiException extends Exception { protected ResponseInterface $responseObject; protected ModelInterface $errorDetails; + protected ?int $retryAfter = null; public function __construct(?string $message = "", ?int $code = 0) { @@ -63,4 +64,14 @@ class ApiException extends Exception { $this->errorDetails = $errorDetails; } + + public function getRetryAfter(): ?int + { + return $this->retryAfter; + } + + public function setRetryAfter(?int $retryAfter): void + { + $this->retryAfter = $retryAfter; + } } \ No newline at end of file diff --git a/template/api.mustache b/template/api.mustache index 9a631e5f..3a3f0cde 100644 --- a/template/api.mustache +++ b/template/api.mustache @@ -137,6 +137,14 @@ use \GuzzleHttp\Exception\GuzzleException; {{/dataType}} {{/responses}} } + + if ($e->getCode() === 429) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int)$response->getHeader('retry-after')); + } + } + throw $e; } } @@ -203,6 +211,14 @@ use \GuzzleHttp\Exception\GuzzleException; {{/dataType}} {{/responses}} } + + if ($e->getCode() === 429) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int)$response->getHeader('retry-after')); + } + } + throw $e; } ); From ad187f36d458b2e95b672271bc9d54480c7bb979 Mon Sep 17 00:00:00 2001 From: Orkun Date: Thu, 29 Aug 2024 12:57:23 +0300 Subject: [PATCH 2/3] chore: regenerate from template --- src/Api/FingerprintApi.php | 28 ++++++++++++++++++++++++++++ src/ApiException.php | 2 +- template/ApiException.mustache | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Api/FingerprintApi.php b/src/Api/FingerprintApi.php index efb46588..a5c40379 100644 --- a/src/Api/FingerprintApi.php +++ b/src/Api/FingerprintApi.php @@ -156,6 +156,13 @@ public function deleteVisitorData(string $visitor_id): array break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } } @@ -233,6 +240,13 @@ function ($e) { break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } ); @@ -676,6 +690,13 @@ public function updateEvent(EventUpdateRequest $body, string $request_id): array break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } } @@ -754,6 +775,13 @@ function ($e) { break; } + if (429 === $e->getCode()) { + $e->setRetryAfter(1); + if ($response->hasHeader('retry-after')) { + $e->setRetryAfter((int) $response->getHeader('retry-after')); + } + } + throw $e; } ); diff --git a/src/ApiException.php b/src/ApiException.php index be7536f6..1905ffe8 100644 --- a/src/ApiException.php +++ b/src/ApiException.php @@ -43,7 +43,7 @@ class ApiException extends \Exception { protected ResponseInterface $responseObject; - protected ModelInterface $errorDetails; + protected ?ModelInterface $errorDetails = null; protected ?int $retryAfter = null; public function __construct(?string $message = '', ?int $code = 0) diff --git a/template/ApiException.mustache b/template/ApiException.mustache index f6a323b7..93dc9388 100644 --- a/template/ApiException.mustache +++ b/template/ApiException.mustache @@ -33,7 +33,7 @@ use Psr\Http\Message\ResponseInterface; class ApiException extends Exception { protected ResponseInterface $responseObject; - protected ModelInterface $errorDetails; + protected ?ModelInterface $errorDetails = null; protected ?int $retryAfter = null; public function __construct(?string $message = "", ?int $code = 0) From 1175aab028d16007aa4e392c5ecb3e5f2775247c Mon Sep 17 00:00:00 2001 From: Orkun Date: Thu, 29 Aug 2024 13:10:26 +0300 Subject: [PATCH 3/3] chore: add test case for retry-after header --- src/Api/FingerprintApi.php | 16 ++++++++-------- template/api.mustache | 4 ++-- test/FingerprintApiTest.php | 8 +++++++- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Api/FingerprintApi.php b/src/Api/FingerprintApi.php index a5c40379..7d13b875 100644 --- a/src/Api/FingerprintApi.php +++ b/src/Api/FingerprintApi.php @@ -159,7 +159,7 @@ public function deleteVisitorData(string $visitor_id): array if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -243,7 +243,7 @@ function ($e) { if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -335,7 +335,7 @@ public function getEvent(string $request_id): array if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -414,7 +414,7 @@ function ($e) { if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -511,7 +511,7 @@ public function getVisits(string $visitor_id, ?string $request_id = null, ?strin if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -595,7 +595,7 @@ function ($e) { if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -693,7 +693,7 @@ public function updateEvent(EventUpdateRequest $body, string $request_id): array if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -778,7 +778,7 @@ function ($e) { if (429 === $e->getCode()) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int) $response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } diff --git a/template/api.mustache b/template/api.mustache index 39c03724..790ac62e 100644 --- a/template/api.mustache +++ b/template/api.mustache @@ -142,7 +142,7 @@ use \GuzzleHttp\Exception\GuzzleException; if ($e->getCode() === 429) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int)$response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } @@ -218,7 +218,7 @@ use \GuzzleHttp\Exception\GuzzleException; if ($e->getCode() === 429) { $e->setRetryAfter(1); if ($response->hasHeader('retry-after')) { - $e->setRetryAfter((int)$response->getHeader('retry-after')); + $e->setRetryAfter((int) $response->getHeader('retry-after')[0]); } } diff --git a/test/FingerprintApiTest.php b/test/FingerprintApiTest.php index b13e9f17..e58ec861 100644 --- a/test/FingerprintApiTest.php +++ b/test/FingerprintApiTest.php @@ -68,6 +68,9 @@ protected function getMockResponse(string $mockId, string $method = "GET", ?stri { $mock_name = ""; $status = 200; + $headers = [ + 'Content-Type' => 'application/json', + ]; if ($method === "GET" || $method === "DELETE") { switch ($mockId) { @@ -111,6 +114,7 @@ protected function getMockResponse(string $mockId, string $method = "GET", ?stri case self::MOCK_VISITOR_ID_429_ERROR: $mock_name = 'get_visits_429_too_many_requests_error.json'; $status = 429; + $headers['retry-after'] = 30; break; case self::MOCK_VISITOR_ID_400_ERROR: $mock_name = "400_error_incorrect_visitor_id.json"; @@ -157,7 +161,7 @@ protected function getMockResponse(string $mockId, string $method = "GET", ?stri $contents = json_encode($visits_mock_data); } - return new Response($status, [], $contents); + return new Response($status, $headers, $contents); } public function testGetEvent() @@ -389,6 +393,7 @@ public function testGetVisits429Error() $this->fingerprint_api->getVisits(self::MOCK_VISITOR_ID_429_ERROR); } catch (ApiException $e) { $this->assertEquals(TooManyRequestsResponse::class, get_class($e->getErrorDetails())); + $this->assertEquals(30, $e->getRetryAfter()); throw $e; } } @@ -492,6 +497,7 @@ public function testDeleteVisitorData429Error() $this->fingerprint_api->deleteVisitorData(self::MOCK_VISITOR_ID_429_ERROR); } catch (ApiException $e) { $this->assertEquals(ErrorCommon429Response::class, get_class($e->getErrorDetails())); + $this->assertEquals(30, $e->getRetryAfter()); throw $e; } }