7
votes

I am using Guzzle concurrency request tool: http://docs.guzzlephp.org/en/latest/quickstart.html#concurrent-requests

My code is similar to the example code:

use GuzzleHttp\Pool;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;

$client = new Client();

$requests = function ($total) {
    $uri = 'http://127.0.0.1:8126/guzzle-server/perf';
    for ($i = 0; $i < $total; $i++) {
        yield new Request('GET', $uri);
    }
};

$pool = new Pool($client, $requests(100), [
    'concurrency' => 5,
    'fulfilled' => function ($response, $index) {
        // this is delivered each successful response
    },
    'rejected' => function ($reason, $index) {
        // this is delivered each failed request
    },
]);

// Initiate the transfers and create a promise
$promise = $pool->promise();

// Force the pool of requests to complete.
$promise->wait();

The issue is that some of my requests return responses with 500 HTTP responses, but still sends some contents (e.g. why the error happened). Guzzle unfortunately classes http responses with 500 status codes as 'rejected', and I cannot seem to get the original response, as that parameter does not exist in the rejected function.

I can however access the $reason. In my case it contained a JSON like so:

{
    xdebug: "..."
}

The xdebug property contains HTML as a string that looks like so:

GuzzleHttp\Exception\ServerException: Server error: `GET http://example.com` resulted in a `500 Internal Server Error` response: {"failure_reason":"Useful message"} in [...stacktrace ...]

Although this contains the original response, I cannot easily extract it as its hidden away in HTML, making it very unuseful. I also have no idea how this is set in the first place.

Therefore my question is, how can I access the response for rejected concurrent requests?

1

1 Answers

17
votes

After some effort I finally managed to answer my own question. The $reason is a GuzzleException.

Therefore we can check what type of exception it is and perform the appropriate logic like so:

[
    ...,
    'rejected' => function ($reason, $index) {
        if ($reason instanceof GuzzleHttp\Exception\ClientException) {
            $body = $reason->getResponse()->getBody();
        }
    },
]

Note that not all GuzzleException has a response. See http://docs.guzzlephp.org/en/latest/quickstart.html#exceptions for more details.