Gostaria de lidar com erros do Guzzle quando o servidor retornar códigos de status 4xx e 5xx. Eu faço uma solicitação como esta:
$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
retorna informações de código, mas não o corpo da resposta HTTP. Como posso obter o corpo da resposta?
Respostas:
Guzzle 3.x
De acordo com os documentos , você pode capturar o tipo de exceção apropriado (
ClientErrorResponseException
para erros 4xx) e chamar seugetResponse()
método para obter o objeto de respostagetBody()
.Passar
true
para agetBody
função indica que você deseja obter o corpo da resposta como uma sequência. Caso contrário, você o receberá como instância da classeGuzzle\Http\EntityBody
.fonte
Guzzle 6.x
De acordo com os documentos , os tipos de exceção que você precisa capturar são:
GuzzleHttp\Exception\ClientException
para erros de nível 400GuzzleHttp\Exception\ServerException
para erros de 500 níveisGuzzleHttp\Exception\BadResponseException
para ambos (é a superclasse deles)O código para lidar com esses erros agora se parece com isso:
fonte
$response->getBody()->getContents()
, retornaria uma string vazia. Eu me deparei com isso nos documentos :\GuzzleHttp\Psr7\str($e->getResponse())
ao transmitir a resposta como uma sequência Psr7, recebi uma mensagem de erro completa e bem formatada.Psr7\str()
teria resultados diferentes para->getContents()
. Você tem um exemplo mínimo demonstrando isso, que pode me deixar entender isso e talvez atualizar esta resposta?'http_errors' => false
opção pode ser aprovada na solicitação Guzzle que desativa o lançamento de exceções. Você pode obter o corpo$response->getBody()
independentemente do código de status e testar o código de status, se necessário$response->getStatusCode()
.$response->getBody()->getContents()
me fornece uma string vazia em um caso, não entendo o porquê. Mas using\GuzzleHttp\Psr7\str()
retorna toda a resposta HTTP como uma string, e eu faria apenas o corpo HTTP. Como dito na documentação , o corpo pode ser usado convertendo-o em string.$stringBody = (string) $clientException->getResponse()->getBody();
\GuzzleHttp\Exception\RequestException
que retornava um400
status. tente {$ request-> api ('POST', 'endpoint.json'); } catch (RequestException $ e) {print_r ($ e-> getResponse () -> getBody () -> getContents ()); }Embora as respostas acima sejam boas, elas não capturam erros de rede. Como Mark mencionou, BadResponseException é apenas uma super classe para ClientException e ServerException. Mas RequestException também é uma super classe de BadResponseException. A RequestException será lançada não apenas para erros de 400 e 500, mas também para erros de rede e redirecionamentos infinitos. Então, digamos que você solicite a página abaixo, mas sua rede está funcionando e sua captura está esperando apenas uma BadResponseException. Bem, seu aplicativo lançará um erro.
Nesse caso, é melhor esperar RequestException e procurar uma resposta.
fonte
JsonResponse
uma aula do Guzzle?JsonResponse
vem de SymfonyA partir de 2019, aqui está o que eu elaborei com as respostas acima e os documentos do Guzzle para lidar com a exceção, obter o corpo da resposta, o código de status, a mensagem e outros itens de resposta às vezes valiosos.
Voila. Você obtém as informações da resposta em itens convenientemente separados.
Notas laterais:
Com a
catch
cláusula, capturamos a classe de exceção raiz PHP da cadeia de herança à\Exception
medida que as exceções personalizadas do Guzzle a estendem.Essa abordagem pode ser útil para casos de uso em que o Guzzle é usado sob o capô, como no Laravel ou no AWS API PHP SDK, para que você não possa capturar a exceção genuína do Guzzle.
Nesse caso, a classe de exceção pode não ser a mencionada nos documentos do Guzzle (por exemplo,
GuzzleHttp\Exception\RequestException
como exceção raiz do Guzzle).Portanto, você precisa entender,
\Exception
mas lembre-se de que ainda é a instância da classe de exceção Guzzle.Embora use com cuidado. Esses invólucros podem tornar
$e->getResponse()
os métodos genuínos do objeto Guzzle não disponíveis. Nesse caso, você terá que examinar o código fonte da exceção real do invólucro e descobrir como obter status, mensagem etc. em vez de usar$response
os métodos do Guzzle .Se você telefonar diretamente para o Guzzle, poderá encontrar um
GuzzleHttp\Exception\RequestException
ou qualquer outro mencionado nos documentos de exceção com relação às condições do seu caso de uso.fonte
$response
objeto ao lidar com exceções, a menos que tenha verificado$e->hasResponse()
, caso contrário,$response
poderá ocorrernull
e qualquer chamada de método causará um erro fatal.$e->hasResponse
o resultado, um método que, é claro, não existe para exceções que não são do Guzzle. Portanto, se você criar uma exceção não-GuzzletheMethodMayThrowException()
, esse código a capturará, tente chamar um método inexistente e trava por causa do método inexistente, ocultando efetivamente a verdadeira causa do erro. Preferível seria pegar emGuzzleHttp\Exception\RequestException
vez deException
evitar isso.se colocar
'http_errors' => false
em opções de solicitação Guzzle, em seguida, ele iria parar exceção lance enquanto get 4xx ou 5xx erro, como esta:$client->get(url, ['http_errors' => false])
. então você analisa a resposta, não importa se está tudo bem ou com erro, ela estaria na resposta para obter mais informaçõesfonte