Я хотел бы обрабатывать ошибки от Guzzle, когда сервер возвращает коды состояния 4xx и 5xx. Я делаю такую просьбу:
$client = $this->getGuzzleClient();
$request = $client->post($url, $headers, $value);
try {
$response = $request->send();
return $response->getBody();
} catch (\Exception $e) {
// How can I get the response body?
}
$e->getMessage
возвращает информацию о коде, но не тело HTTP-ответа. Как получить тело ответа?
Ответы:
Жрать 3.x
в документации , вы можете поймать соответствующий тип исключения (
ClientErrorResponseException
для ошибок 4xx) и вызвать егоgetResponse()
метод, чтобы получить объект ответа, а затем вызвать егоgetBody()
:Переходя
true
кgetBody
функции означает, что вы хотите получить тело ответа в виде строки. В противном случае вы получите его как экземпляр классаGuzzle\Http\EntityBody
.источник
Жрать 6.x
Согласно документации , вам могут потребоваться следующие типы исключений:
GuzzleHttp\Exception\ClientException
для 400-уровневых ошибокGuzzleHttp\Exception\ServerException
для 500-уровневых ошибокGuzzleHttp\Exception\BadResponseException
для обоих (это их суперкласс)Код для обработки таких ошибок теперь выглядит примерно так:
источник
$response->getBody()->getContents()
вернет пустую строку. Затем я наткнулся на это в документации :\GuzzleHttp\Psr7\str($e->getResponse())
преобразование ответа в виде строки Psr7 дало мне хорошо отформатированное и полное сообщение об ошибке.Psr7\str()
будет иметь разные результаты к->getContents()
. У вас есть минимальный пример, демонстрирующий это, который мог бы позволить мне понять это и, возможно, обновить этот ответ?'http_errors' => false
параметр может быть передан в запросе Guzzle, который отключает выдачу исключений. Затем вы можете получить тело с$response->getBody()
любым кодом состояния, и вы можете проверить код состояния, если это необходимо, с помощью$response->getStatusCode()
.$response->getBody()->getContents()
в одном случае дает мне пустую строку, я не понимаю, почему. Но использование\GuzzleHttp\Psr7\str()
возвращает весь ответ HTTP в виде строки, а я бы только тело HTTP. Как сказано в документации , тело можно использовать, преобразовав его в строку.$stringBody = (string) $clientException->getResponse()->getBody();
\GuzzleHttp\Exception\RequestException
вместо этого я получал сообщение , возвращающее400
код состояния. попробуйте {$ request-> api ('POST', 'endpoint.json'); } catch (RequestException $ e) {print_r ($ e-> getResponse () -> getBody () -> getContents ()); }Хотя приведенные выше ответы хороши, они не обнаруживают сетевых ошибок. Как уже упоминал Марк, BadResponseException - это просто суперкласс для ClientException и ServerException. Но RequestException также является суперклассом BadResponseException. RequestException будет сгенерирован не только для ошибок 400 и 500, но и для сетевых ошибок и бесконечных перенаправлений. Допустим, вы запрашиваете страницу ниже, но ваша сеть работает, и ваш улов ожидает только исключения BadResponseException. Что ж, ваше приложение выдаст ошибку.
В этом случае лучше ожидать RequestException и проверять наличие ответа.
источник
JsonResponse
класс от жрать?JsonResponse
приходит с SymfonyПо состоянию на 2019 год, вот что я разработал на основе приведенных выше ответов и документов Guzzle для обработки исключения, получения тела ответа, кода состояния, сообщения и других иногда ценных элементов ответа.
Вуаля. Вы получаете информацию об ответе в виде удобно разделенных элементов.
Боковые примечания:
С помощью
catch
предложения мы перехватываем класс корневых исключений PHP в цепочке наследования,\Exception
поскольку пользовательские исключения Guzzle расширяют его.Этот подход может быть полезен в тех случаях, когда Guzzle используется под капотом, например, в Laravel или AWS API PHP SDK, поэтому вы не можете поймать настоящее исключение Guzzle.
В этом случае класс исключения может не совпадать с тем, который упоминается в документации Guzzle (например,
GuzzleHttp\Exception\RequestException
как корневое исключение для Guzzle).Поэтому вам нужно поймать
\Exception
вместо этого, но имейте в виду, что это все еще экземпляр класса исключения Guzzle.Хотя используйте с осторожностью. Эти оболочки могут сделать недоступными
$e->getResponse()
подлинные методы объекта Guzzle . В этом случае вам нужно будет посмотреть на фактический исходный код исключения оболочки и выяснить, как получить статус, сообщение и т. Д. Вместо использования методов Guzzle$response
.Если вы сами вызываете Guzzle напрямую, вы можете поймать
GuzzleHttp\Exception\RequestException
или любой другой, упомянутый в их документации по исключениям в отношении условий вашего варианта использования.источник
$response
объекта при обработке исключений, если вы не проверили$e->hasResponse()
, иначе это$response
может быть,null
и любой вызов метода вызовет фатальную ошибку.$e->hasResponse
результат, метод, который, конечно, не существует для исключений, отличных от Guzzle. Поэтому, если вы вызовете исключение, отличное от GuzzletheMethodMayThrowException()
, этот код перехватит его, попытается вызвать несуществующий метод и выйдет из строя из -за несуществующего метода, эффективно скрывая истинную причину ошибки. Лучше было бы поймать,GuzzleHttp\Exception\RequestException
а неException
избегать этого.если положить
'http_errors' => false
в жрать параметры запроса, то это было бы остановить бросить исключение при прибудет 4xx или 5xx ошибки, как это:$client->get(url, ['http_errors' => false])
. затем вы анализируете ответ, независимо от того, в порядке ли он или ошибка, это будет в ответе для получения дополнительной информацииисточник