From 3aedb51dd8f79efc8e60d2a249d10dfb3b0c6082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Fri, 2 Oct 2020 11:04:50 +0200 Subject: [PATCH] [HttpClient] Fix exception triggered with AsyncResponse --- .../HttpClient/Response/AsyncResponse.php | 10 +++++----- .../HttpClient/Tests/AsyncDecoratorTraitTest.php | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/HttpClient/Response/AsyncResponse.php b/src/Symfony/Component/HttpClient/Response/AsyncResponse.php index a3375e3dc8..42cd3a841e 100644 --- a/src/Symfony/Component/HttpClient/Response/AsyncResponse.php +++ b/src/Symfony/Component/HttpClient/Response/AsyncResponse.php @@ -206,6 +206,11 @@ final class AsyncResponse implements ResponseInterface, StreamableInterface foreach ($client->stream($wrappedResponses, $timeout) as $response => $chunk) { $r = $asyncMap[$response]; + if (null === $chunk->getError() && $chunk->isFirst()) { + // Ensure no exception is thrown on destruct for the wrapped response + $r->response->getStatusCode(); + } + if (!$r->passthru) { if (null !== $chunk->getError() || $chunk->isLast()) { unset($asyncMap[$response]); @@ -219,11 +224,6 @@ final class AsyncResponse implements ResponseInterface, StreamableInterface continue; } - if (null === $chunk->getError() && $chunk->isFirst()) { - // Ensure no exception is thrown on destruct for the wrapped response - $r->response->getStatusCode(); - } - foreach (self::passthru($r->client, $r, $chunk, $asyncMap) as $chunk) { yield $r => $chunk; } diff --git a/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php b/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php index 9dd745152d..363d078ea5 100644 --- a/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php +++ b/src/Symfony/Component/HttpClient/Tests/AsyncDecoratorTraitTest.php @@ -62,6 +62,22 @@ class AsyncDecoratorTraitTest extends NativeHttpClientTest $this->assertSame(200, $response->getStatusCode()); } + public function testRetry404WithThrow() + { + $client = $this->getHttpClient(__FUNCTION__, function (ChunkInterface $chunk, AsyncContext $context) { + $this->assertTrue($chunk->isFirst()); + $this->assertSame(404, $context->getStatusCode()); + $context->getResponse()->cancel(); + $context->replaceRequest('GET', 'http://localhost:8057/404'); + $context->passthru(); + }); + + $response = $client->request('GET', 'http://localhost:8057/404'); + + $this->expectException(ClientExceptionInterface::class); + $response->getContent(true); + } + public function testRetryTransportError() { $client = $this->getHttpClient(__FUNCTION__, function (ChunkInterface $chunk, AsyncContext $context) {