2013-11-02 5 views
49

Ich möchte Fehler von Guzzle behandeln, wenn der Server 4xx und 5xx Statuscodes zurückgibt. Ich mache eine Anfrage wie folgt aus:Handle Guzzle Ausnahme und HTTP-Körper erhalten

$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 kehrt Code Info aber nicht der Körper der HTTP-Antwort. Wie kann ich den Antwortkörper erhalten?

+0

wird diese Frage auf diese Frage im Zusammenhang http://stackoverflow.com/questions/17658283/catching-exceptions-from-guzzle/28416973#28416973 und die Antworten könnte es eine Hilfe sein, auch. – Trendfischer

Antwort

46

Guzzle 3.x

Per the docs, können Sie den entsprechenden Ausnahmetyp (ClientErrorResponseException für 4xx-Fehler) fangen und rufen seine getResponse() Methode, um das Antwort-Objekt zu erhalten, rufen Sie getBody() auf, dass:

use Guzzle\Http\Exception\ClientErrorResponseException; 

... 

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

Die Übergabe von true an die Funktion getBody bedeutet, dass Sie den Antworttext als Zeichenfolge abrufen möchten. Andernfalls erhalten Sie es als Instanz der Klasse Guzzle\Http\EntityBody. 6.x

116

Guzzle

Per the docs, die Ausnahmetypen müssen Sie möglicherweise fangen sind:

  • GuzzleHttp\Exception\ClientException für 400-Level-Fehler
  • GuzzleHttp\Exception\ServerException für 500-Level-Fehler
  • GuzzleHttp\Exception\BadResponseException für beide (es ist ihre Oberklasse)

-Code auf solche Fehler behandeln so sieht nun ungefähr so:

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

Für mich '$ response-> getBody() -> getContents()' würde eine leere Zeichenfolge zurückgeben. Ich stolperte dann darüber in [die Dokumente] (https://github.com/guzzle/guzzle/blob/master/docs/quickstart.rst): '\ GuzzleHttp \ Psr7 \ str ($ e-> getResponse ()) ' Casting die Antwort als eine PSR7 String hat mir eine schön formatierte und vollständige Fehlermeldung. –

+3

@AndyPlace, nachdem ich einen Blick auf PSR 7 geworfen habe (auf die der Abschnitt der Dokumentation, auf den ich zu der Zeit, als ich diese Antwort geschrieben habe, nicht verlinkt ist) nicht sofort offensichtlich ist, warum ich 'Psr7 \ str() 'hätte andere Ergebnisse als' -> getContents() '. Haben Sie ein minimales Beispiel, das dies zeigt, das mich das vielleicht verstehen lässt und vielleicht diese Antwort aktualisiert? –

+1

Erwähnenswert ist, dass die Option "http_errors => false" in der Guzzle-Anforderung übergeben werden kann, die das Auslösen von Ausnahmen verhindert.Sie können dann den Body mit '$ response-> getBody()' unabhängig vom Statuscode erhalten, und Sie können den Statuscode bei Bedarf mit '$ response-> getStatusCode()' testen. – tremby

18

Während die oben genannten Antworten gut sind, werden sie nicht mit Netzwerkfehler umgehen, wie Mark erwähnt BadResponseException für ClientException und Serverexception nur eine Superklasse ist. Aber RequestException ist auch eine Super-Klasse von BadRequestException. Dies wird nicht nur 400 und 500 Fehler sondern auch Netzwerkfehler abfangen. Nehmen wir an, Sie fordern die unten stehende Seite an, aber Ihr Netzwerk spielt auf und Ihr Catch erwartet eine BadResponseException. Nun, Ihre Anwendung wird einen Fehler auslösen.

In diesem Fall ist es besser, RequestException zu erwarten und nach einer Antwort zu suchen.

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

}