diff --git a/src/ClientFactory.php b/src/ClientFactory.php index 4c2d5ac7..0f746df6 100644 --- a/src/ClientFactory.php +++ b/src/ClientFactory.php @@ -13,13 +13,18 @@ namespace JoliCode\Slack; +use Http\Client\Common\Exception\ClientErrorException; use Http\Client\Common\Plugin\ErrorPlugin; use Http\Client\Common\Plugin\HeaderAppendPlugin; +use Http\Client\Common\Plugin\RetryPlugin; use Http\Client\Common\PluginClient; +use Http\Client\Exception\HttpException; use Http\Discovery\Psr17FactoryDiscovery; use Http\Discovery\Psr18ClientDiscovery; use JoliCode\Slack\HttpPlugin\AddSlackPathAndHostPlugin; use JoliCode\Slack\HttpPlugin\SlackErrorPlugin; +use Psr\Http\Client\ClientExceptionInterface; +use Psr\Http\Message\RequestInterface; use Psr\Http\Client\ClientInterface; class ClientFactory @@ -34,12 +39,30 @@ public static function create(string $token, ?ClientInterface $httpClient = null // Decorates the HTTP client with some plugins $uri = Psr17FactoryDiscovery::findUriFactory()->createUri('https://slack.com/api'); $pluginClient = new PluginClient($httpClient, [ - new ErrorPlugin(), new SlackErrorPlugin(), new AddSlackPathAndHostPlugin($uri), new HeaderAppendPlugin([ 'Authorization' => 'Bearer ' . $token, ]), + new RetryPlugin([ + 'retries' => 3, + 'exception_decider' => function (RequestInterface $request, ClientExceptionInterface $e) { + // retry only server errors and rate limits + return !$e instanceof HttpException || ($e->getCode() === 429 || ($e->getCode() >= 500 && $e->getCode() < 600)); + }, + 'exception_delay' => function (RequestInterface $request, ClientExceptionInterface $e, int $retries): int { + if ($e instanceof ClientErrorException) { + $response = $e->getResponse(); + if ($response->hasHeader('Retry-After')) { + $retryAfter = (int) $response->getHeaderLine('retry-after'); + return $retryAfter * 1000000; + } + } + + return RetryPlugin::defaultExceptionDelay($request, $e, $retries); + }, + ]), + new ErrorPlugin(), ]); // Instantiate our client extending the one generated by Jane