Me gustaría manejar los errores de Guzzle cuando el servidor devuelve códigos de estado 4xx y 5xx. Hago una petición 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
devuelve información del código pero no el cuerpo de la respuesta HTTP. ¿Cómo puedo obtener el cuerpo de la respuesta?
Según the docs, los tipos de excepción que puedes necesitar atrapar son:
GuzzleHttp\Exception\ClientException
para errores de nivel 400GuzzleHttp\Exception\ServerException
para errores de nivel 500GuzzleHttpException\BadResponseException
para ambos (es su superclase)Por lo tanto, el código para manejar estos errores ahora se parece a esto:
$client = new GuzzleHttp\Client;
try {
$client->get('http://google.com/nosuchpage');
}
catch (GuzzleHttp\Exception\ClientException $e) {
$response = $e->getResponse();
$responseBodyAsString = $response->getBody()->getContents();
}
Según la documentación, puedes capturar el tipo de excepción apropiado (ClientErrorResponseException
para errores 4xx) y llamar a su método getResponse()
para obtener el objeto de respuesta, y luego llamar a getBody()
sobre él:
use Guzzle\Http\Exception\ClientErrorResponseException;
...
try {
$response = $request->send();
} catch (ClientErrorResponseException $exception) {
$responseBody = $exception->getResponse()->getBody(true);
}
Pasar true
a la función getBody
indica que quieres obtener el cuerpo de la respuesta como una cadena. En caso contrario lo obtendrá como una instancia de la clase Guzzle\HttpEntityBody
.
Como Mark mencionó, BadResponseException es sólo una superclase para ClientException y ServerException. Pero RequestException es también una superclase de BadRequestException. Esto atrapará no sólo errores 400 y 500 sino también errores de red. Así que digamos que solicitas la página de abajo pero tu red no funciona y tu captura espera una BadResponseException. Bien, tu aplicación lanzará un error.
En este caso es mejor esperar una RequestException y comprobar si hay respuesta.
try {
$client->get('http://123123123.com')
} catch (RequestException $e) {
// If there are network errors, we need to ensure the application doesn't crash.
// if $e->hasResponse is not null we can attempt to get the message
// Otherwise, we'll just pass a network unavailable message.
if ($e->hasResponse()) {
$exception = (string) $e->getResponse()->getBody();
$exception = json_decode($exception);
return new JsonResponse($exception, $e->getCode());
} else {
return new JsonResponse($e->getMessage(), 503);
}
}