Доступ к ответу на отклоненные параллельные запросы в Guzzle

#guzzle #guzzle6

#guzzle #guzzle6

Вопрос:

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

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

 use GuzzleHttpPool;
use GuzzleHttpClient;
use GuzzleHttpPsr7Request;

$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: ошибка сервера: `ПОЛУЧИТЬ http://example.com ` привело к ответу `500 Internal Server Error`: {«failure_reason»:»Полезное сообщение»} в […stacktrace …]

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

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

Ответ №1:

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

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

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

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

Комментарии:

1. Отличный ответ — документация по этому вопросу очень неоднозначна.