-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Open
Description
Symfony version(s) affected
5.4.42
Description
On timeout RetryableHttpClient
does not call retry strategy when RetryableHttpClient
is decorated with client that returns AsyncResponse
.
If I reverse decoration order then it works.
If I just return parent response then it works too.
I need to decorate client with AsyncResponse and passthru so I can log requests and responses.
it's not working on both 5.4.42 and 6.4.10.
How to reproduce
<?php
declare(strict_types=1);
namespace App\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpClient\AsyncDecoratorTrait;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpClient\Response\AsyncContext;
use Symfony\Component\HttpClient\Response\AsyncResponse;
use Symfony\Component\HttpClient\Retry\RetryStrategyInterface;
use Symfony\Component\HttpClient\RetryableHttpClient;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\HttpClient\ResponseInterface;
use Symfony\Contracts\HttpClient\Test\TestHttpServer;
class UnitTest extends TestCase
{
public function testIssue()
{
$strategy = new class() implements RetryStrategyInterface {
public bool $isCalled = false;
public function shouldRetry(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): ?bool
{
$this->isCalled = true; // this should always get called
return false;
}
public function getDelay(AsyncContext $context, ?string $responseContent, ?TransportExceptionInterface $exception): int
{
return 0;
}
};
$client = HttpClient::create();
$client = new RetryableHttpClient(
client: $client,
strategy: $strategy,
);
// if this is removed or moved above RetryableHttpClient, then it works as expected
$client = new class($client) implements HttpClientInterface
{
use AsyncDecoratorTrait;
public function request(string $method, string $url, array $options = []): ResponseInterface
{
return new AsyncResponse($this->client, $method, $url, $options);
}
};
TestHttpServer::start();
/** @see vendor/symfony/http-client-contracts/Test/Fixtures/web/index.php */
$response = $client->request('GET', 'http://localhost:8057/timeout-header', ['timeout' => 0.1]);
try {
$response->getStatusCode();
self::fail();
} catch (TransportExceptionInterface $e) {
self::assertSame('Idle timeout reached for "http://localhost:8057/timeout-header".', $e->getMessage());
self::assertTrue($strategy->isCalled);
}
}
}
Possible Solution
No response
Additional Context
No response