Получите доступ к ответу на отклоненные параллельные запросы в Guzzle

Я использую инструмент запроса параллелизма Guzzle: http://docs.guzzlephp.org/en/latest/quickstart.html#concurrent-requests

Мой код похож на пример кода:

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();

Проблема в том, что некоторые из моих запросов возвращают ответы с 500 HTTP-ответами, но все же отправляют некоторое содержимое (например, почему произошла ошибка). К сожалению, Guzzle классифицирует HTTP-ответы с 500 кодами состояния как «отклоненные», и я не могу получить исходный ответ, так как этот параметр не существует в отклоненной функции.

Однако я могу получить доступ к $reason. В моем случае он содержал такой JSON:

{
    xdebug: "..."
}

Свойство xdebug содержит HTML в виде строки, которая выглядит так:

GuzzleHttp \ Exception \ ServerException: ошибка сервера: `GET http://example.com%60 привела к ошибке` 500 Internal Ответ на ошибку сервера: {"failure_reason": "Useful message"} в [... stacktrace ...]

Хотя он содержит исходный ответ, я не могу легко извлечь его, поскольку он скрыт в HTML, что делает его очень бесполезным. Я также понятия не имею, как это вообще установлено.

Поэтому мой вопрос: как мне получить доступ к ответу на отклоненные параллельные запросы?


person Yahya Uddin    schedule 13.10.2016    source источник


Ответы (1)


После некоторых усилий мне наконец удалось ответить на свой вопрос. $reason - это GuzzleException.

Поэтому мы можем проверить, что это за исключение, и выполнить соответствующую логику, например:

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

Обратите внимание, что не все исключения GuzzleException имеют ответ. См. http://docs.guzzlephp.org/en/latest/quickstart.html#exceptions для получения более подробной информации.

person Yahya Uddin    schedule 13.10.2016
comment
Отличный ответ - документация по этому поводу очень неоднозначна. - person AndrewMcLagan; 03.10.2019