2013-11-02 18 views
49

Vorrei gestire gli errori di Guzzle quando il server restituisce i codici di stato 4xx e 5xx. Faccio una richiesta del genere:Handle Guzzle exception e get HTTP body

$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 restituisce informazioni codice, ma non il corpo della risposta HTTP. Come posso ottenere il corpo della risposta?

+0

Questa domanda è legata a questa domanda http://stackoverflow.com/questions/17658283/catching-exceptions-from-guzzle/28416973#28416973 e le risposte ci potrebbe essere di qualche aiuto, anche. – Trendfischer

risposta

46

Guzzle 3.x

Per the docs, si può prendere il tipo di eccezione appropriata (ClientErrorResponseException per 4xx errori) e chiamare il suo metodo getResponse() per ottenere l'oggetto risposta, quindi chiamare getBody() su quella:

use Guzzle\Http\Exception\ClientErrorResponseException; 

... 

try { 
    $response = $request->send(); 
} catch (ClientErrorResponseException $exception) { 
    $responseBody = $exception->getResponse()->getBody(true); 
} 

Il passaggio true alla funzione getBody indica che si desidera ottenere il corpo della risposta come una stringa. Altrimenti lo riceverai come istanza della classe Guzzle\Http\EntityBody.

116

Guzzle 6.x

Per the docs, i tipi di eccezione che potrebbe essere necessario per la cattura sono:

  • GuzzleHttp\Exception\ClientException per errori di livello 400
  • GuzzleHttp\Exception\ServerException per gli errori 500 a livello
  • GuzzleHttp\Exception\BadResponseException per entrambi (è la loro superclasse)

codice per gestire tali errori così ora simile a questa:

$client = new GuzzleHttp\Client; 
try { 
    $client->get('http://google.com/nosuchpage');  
} 
catch (GuzzleHttp\Exception\ClientException $e) { 
    $response = $e->getResponse(); 
    $responseBodyAsString = $response->getBody()->getContents(); 
} 
+6

Per me '$ response-> getBody() -> getContents()' restituisce una stringa vuota. poi mi sono imbattuto in questo [la documentazione] (https://github.com/guzzle/guzzle/blob/master/docs/quickstart.rst): '\ GuzzleHttp \ Psr7 \ str ($ e-> getResponse ()) ' Casting la risposta come stringa Psr7 mi ha fatto un messaggio di errore formattata e completo. –

+3

@AndyPlace dopo aver preso uno sguardo al PSR 7 (che non è stato riferito dalla sezione dei documenti che ho Link a nel momento in cui ho scritto questa risposta, ma è ora) non è immediatamente evidente per me perché chiamare 'Psr7 \ str() 'avrebbe risultati diversi per' -> getContents() '. Hai un esempio minimale che dimostri questo, che potrebbe farmi capire questo e forse aggiornare questa risposta? –

+1

Vale la pena ricordare che il 'http_errors' => false' opzione 'può essere passato nella richiesta Guzzle che disabilita generare eccezioni.Puoi quindi ottenere il corpo con '$ response-> getBody()' indipendentemente dal codice di stato, e puoi testare il codice di stato se necessario con '$ response-> getStatusCode()'. – tremby

18

Mentre le risposte di cui sopra sono buone che non trattare con errori di rete, come Mark accennato BadResponseException è solo una classe di super per ClientException e ServerException. Ma RequestException è anche una super classe di BadRequestException. Questo catturerà non solo gli errori 400 e 500 ma anche gli errori di rete. Supponiamo che tu richieda la pagina seguente, ma la tua rete è in fase di riproduzione e il tuo pescato si aspetta una BadResponseException. Bene, la tua applicazione genererà un errore.

In questo caso è meglio prevedere RequestException e controllare la risposta.

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); 
    } 

}