#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. Отличный ответ — документация по этому вопросу очень неоднозначна.