diff --git a/.gitignore b/.gitignore index 05ca60cc..35190a88 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ composer.lock *.sh script/* +# IDE +.idea + # Testing /phpunit.xml /build diff --git a/src/Bigcommerce/Api/Connection.php b/src/Bigcommerce/Api/Connection.php index b84e0618..45e980c6 100644 --- a/src/Bigcommerce/Api/Connection.php +++ b/src/Bigcommerce/Api/Connection.php @@ -86,6 +86,16 @@ class Connection */ private $contentType; + /** + * Total number of times to automatically retry request if API rate limit is reached. + */ + private $maxRetries = 3; + + /** + * Number of times request has been retried. + */ + private $autoRetries = 0; + /** * Initializes the connection object. */ @@ -281,6 +291,13 @@ private function handleResponse() $status = $this->getStatus(); + if ($this->apiRateLimitReached($status)) { + if ($this->autoRetries < $this->maxRetries) { + $this->autoRetries++; + return $this->replayRequest(); + } + } + if ($status >= 400 && $status <= 499) { if ($this->failOnError) { throw new ClientError($body, $status); @@ -297,6 +314,8 @@ private function handleResponse() } } + $this->autoRetries = 0; + if ($this->followLocation) { $this->followRedirectPath(); } @@ -304,6 +323,20 @@ private function handleResponse() return $body; } + public function apiRateLimitReached($status) + { + return $status == 429; + } + + public function replayRequest() + { + $secondsToWait = $this->getHeader('X-Retry-After'); + sleep($secondsToWait); + curl_exec($this->curl); + + $this->handleResponse(); + } + /** * Return an representation of an error returned by the last request, or false * if the last request was not an error.