Skip to content

Commit

Permalink
Improve rate limit handling in the SDK
Browse files Browse the repository at this point in the history
  • Loading branch information
szeber committed Oct 8, 2017
1 parent ea5475b commit 26ee921
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 7 deletions.
26 changes: 20 additions & 6 deletions src/ShoppinPal/Vend/Api/BaseApiAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use ShoppinPal\Vend\Auth\AuthHelper;
use ShoppinPal\Vend\Exception\CommunicationException;
use ShoppinPal\Vend\Exception\EntityNotFoundException;
use ShoppinPal\Vend\Exception\RateLimitingException;
use YapepBase\Application;
use YapepBase\Communication\CurlHttpRequest;

Expand Down Expand Up @@ -85,19 +86,32 @@ protected function getAuthenticatedRequestForUri($path, array $params = [], $ski
*
* @return array|null
* @throws EntityNotFoundException
* @throws RateLimitingException
* @throws CommunicationException
*/
protected function sendRequest(CurlHttpRequest $request, $requestType)
{
$result = $request->send();

if (!$result->getError() && 404 == $result->getResponseCode()) {
throw new EntityNotFoundException('The specified entity can not be found', 404, null, $result);
}

if (!$result->isRequestSuccessful()) {
if (!$result->getError()) {
switch ($result->getResponseCode()) {
case 404:
throw new EntityNotFoundException('The specified entity can not be found', 404, null, $result);

case 429:
throw new RateLimitingException(
$requestType,
$result,
'Your access to the API has been rate limited',
429,
null
);
}
}

$exceptionClass = $this->getCommunicationExceptionClass();
throw new $exceptionClass($requestType, $result, 0, null, $result);
throw new $exceptionClass($requestType, $result, 0, null);
}

if (204 == $result->getResponseCode()) {
Expand All @@ -108,7 +122,7 @@ protected function sendRequest(CurlHttpRequest $request, $requestType)

if (empty($resultData)) {
$exceptionClass = $this->getCommunicationExceptionClass();
throw new $exceptionClass($requestType, $result, 0, null, $result);
throw new $exceptionClass($requestType, $result, 0, null);
}

return $resultData;
Expand Down
2 changes: 1 addition & 1 deletion src/ShoppinPal/Vend/Exception/CommunicationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function __construct(
$this->curlResult = $curlResult;
$this->requestType = $requestType;

parent::__construct($message, $code, $previous, $data);
parent::__construct($message, $code, $previous, $data ?: $curlResult);
}

/**
Expand Down
39 changes: 39 additions & 0 deletions src/ShoppinPal/Vend/Exception/RateLimitingException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

namespace ShoppinPal\Vend\Exception;

use DateTime;
use YapepBase\Exception\Exception;

/**
* Thrown if the request is denied because of rate limiting
*/
class RateLimitingException extends CommunicationException
{

/**
* @return DateTime
* @throws Exception
*/
public function getRetryAfter()
{
$responseBody = $this->curlResult->getResponseBody();
$decodedBody = json_decode($responseBody, true);

if (empty($decodedBody)) {
throw new Exception('Unable to decode response body: ' . $responseBody);
}

if (!isset($decodedBody['retry-after'])) {
throw new Exception('No retry-after in response body: ' . $responseBody);
}

$retryAfter = DateTime::createFromFormat(DateTime::RFC822, $decodedBody['retry-after']);

if (empty($retryAfter)) {
throw new Exception('Unable to parse date from retry-after string: ' . $decodedBody['retry-after']);
}

return $retryAfter;
}
}

0 comments on commit 26ee921

Please sign in to comment.