Skip to content

[HttpClient] Stream throws sometimes #32673

Closed
@Toflar

Description

@Toflar

Symfony version(s) affected: 4.3.*

Description

According to the Symfony docs, HttpClientInterface::stream() is not supposed to throw any errors but it seems like under some circumstances that's still the case.

How to reproduce

It's pretty hard to reproduce because for me it seems to happen when I get a 502 server response but I wasn't able to mock it to create a test case. But maybe the stack trace can already help.
So this is the code I used:

namespace MyProject;

class MyClass
{
    public function processResponses(array $responses): void
    {
        foreach ($this->getClient()->stream($responses) as $response => $chunk) {
            try {
                // Whatever is not 200 OK is not going to be processed any further
                if (200 !== $response->getStatusCode()) {
                    $response->cancel();
                    continue; // TODO: is that even needed? Does cancel() always turn into a TransportException?
                }
 
                if ($chunk->isLast()) {
                    // Process
                    $this->processResponse($response);
                }
            } catch (TransportExceptionInterface | RedirectionExceptionInterface | ClientExceptionInterface | ServerExceptionInterface $e) {
                // I should land here
            }
        }
    }
}

Stacktrace:

PHP Fatal error:  Uncaught Symfony\Component\HttpClient\Exception\ServerException: HTTP/2 502  returned for "https://demo-url.com/foobar.html". in /project/vendor/symfony/http-client/Response/ResponseTrait.php:229
Stack trace:
#0 /project/vendor/symfony/http-client/Response/ResponseTrait.php(86): Symfony\Component\HttpClient\Response\CurlResponse->checkStatusCode()
#1 /project/vendor/symfony/http-client/Response/ResponseTrait.php(333): Symfony\Component\HttpClient\Response\CurlResponse->getHeaders(true)
#2 [internal function]: Symfony\Component\HttpClient\Response\CurlResponse::stream(Array, NULL)
#3 /project/vendor/symfony/http-client/Response/ResponseStream.php(44): Generator->next()
#4 /project/src/MyClass.php(262): Symfony\Component\HttpClient\Response\ResponseStream->next()
#5 /project/src/MyClass.php(256): MyProject\MyClass->processResponses(Array)

Possible Solution

Depending on what I do I also get this sometimes during CurlResponse::__destruct() so I think the issue here is that under some circumstances (I kind of think when just no chunk arrives) stream() still throws which should not happen. So it's also related to #31187 because as you can see I'm actually trying to catch the ServerExceptionInterface inside my loop :)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions