Skip to content

Commit

Permalink
fix: auto retry when "too many request" error from API
Browse files Browse the repository at this point in the history
  • Loading branch information
darkdarin committed Nov 29, 2023
1 parent 5a1ed18 commit 2c953d2
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/DTO/Response.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public function __construct(
public mixed $result = null,
public ?int $error_code = null,
public ?string $description = null,
public ?ResponseParameters $parameters = null,
) {}
}
16 changes: 16 additions & 0 deletions src/DTO/ResponseParameters.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

namespace DarkDarin\TelegramBotSdk\DTO;

/**
* Describes why a request was unsuccessful.
*
* @link https://core.telegram.org/bots/api#responseparameters
*/
readonly class ResponseParameters
{
public function __construct(
public ?int $migrate_to_chat_id = null,
public ?int $retry_after = null,
) {}
}
20 changes: 17 additions & 3 deletions src/TransportClient/TransportClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
class TransportClient implements TransportClientInterface
{
private const BASE_URL = 'https://api.telegram.org';
private const MAX_RETRY = 10;

public function __construct(
private readonly ClientInterface $client,
Expand Down Expand Up @@ -55,9 +56,22 @@ public function executeMethod(
} else {
$request = $this->makeJsonRequest($method, $parameters);
}
$rawResponse = $this->client->sendRequest($request);
/** @var Response $response */
$response = $this->serializer->deserialize($rawResponse->getBody()->getContents(), Response::class, 'json');

$result = false;
$retryCount = 0;

do {
$retryCount++;
$rawResponse = $this->client->sendRequest($request);
/** @var Response $response */
$response = $this->serializer->deserialize($rawResponse->getBody()->getContents(), Response::class, 'json');
// If returned "Too many requests" - retry after some time
if ($response->error_code === 429) {
sleep($response->parameters?->retry_after ?? 1);
continue;
}
$result = true;
} while (!$result || $retryCount >= self::MAX_RETRY);

if ($response->error_code !== null || $rawResponse->getStatusCode() !== 200) {
throw new TelegramException(
Expand Down

0 comments on commit 2c953d2

Please sign in to comment.