webentwicklung-frage-antwort-db.com.de

Behandle die Guzzle-Ausnahme und erhalte den HTTP-Body

Ich möchte Fehler von Guzzle behandeln, wenn der Server die Statuscodes 4xx und 5xx zurückgibt. Ich mache eine Anfrage wie folgt:

$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 gibt Code-Informationen zurück, jedoch nicht den Hauptteil der HTTP-Antwort. Wie kann ich den Antworttext erhalten?

96
domos

3.x abspritzen

Per the docs können Sie den entsprechenden Ausnahmetyp abfangen (ClientErrorResponseException für 4xx-Fehler) und die getResponse() -Methode aufrufen, um das Antwortobjekt abzurufen, und dann getBody() dazu:

use Guzzle\Http\Exception\ClientErrorResponseException;

...

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

Wenn Sie true an die Funktion getBody übergeben, wird angezeigt, dass Sie den Antworttext als Zeichenfolge abrufen möchten. Andernfalls erhalten Sie es als Instanz der Klasse Guzzle\Http\EntityBody.

62
sebbo

Düse 6.x.

Per the docs müssen möglicherweise folgende Ausnahmetypen abgefangen werden:

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

Der Code zur Behandlung solcher Fehler sieht also jetzt ungefähr so ​​aus:

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

Obwohl die obigen Antworten gut sind, werden sie keine Netzwerkfehler behandeln. Wie Mark bereits erwähnte, ist BadResponseException nur eine Superklasse für ClientException und ServerException. Aber RequestException ist auch eine Superklasse von BadRequestException. Dies fängt nicht nur 400 und 500 Fehler, sondern auch Netzwerkfehler ab. Nehmen wir also an, Sie fordern die folgende Seite an, aber Ihr Netzwerk ist in Betrieb und Ihr Fang erwartet eine BadResponseException. Nun, Ihre Anwendung wird einen Fehler auslösen.

In diesem Fall ist es besser, RequestException zu erwarten und auf eine Antwort zu prüfen.

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

}
42
chap

Ab 2019 habe ich aus den obigen Antworten und Guzzle docs Folgendes herausgearbeitet, um die Ausnahme zu behandeln, den Antworttext, den Statuscode, die Nachricht und die anderen manchmal wertvollen Antwortelemente abzurufen.

try {
    /**
     * We use Guzzle to make an HTTP request somewhere in the
     * following theMethodMayThrowException().
     */
    $result = theMethodMayThorwException();
} catch (\Exception $e) {
    /**
     * Here we actually catch the instance of GuzzleHttp\Psr7\Response
     * (find it in ./vendor/guzzlehttp/psr7/src/Response.php) with all
     * its own and its 'Message' trait's methods. See more explanations below.
     *
     * So you can have: HTTP status code, message, headers and body.
     */
    $response = $e->getResponse();
    var_dump($response->getStatusCode()); // HTTP status code
    var_dump($response->getReasonPhrase()); // Message
    var_dump((string) $response->getBody()); // Body
    var_dump($response->getHeaders()); // Headers array
    var_dump($response->hasHeader('Content-Type')); // Is the header presented
    var_dump($response->getHeader('Content-Type')[0]); // Concrete header value
}
// process $result etc. ...

Voila. Sie erhalten die Antwortinformationen in bequem getrennten Elementen.

Randbemerkungen:

Mit der catch -Klausel wird die Vererbungskette PHP Root-Ausnahmeklasse \Exception] Abgefangen, wenn benutzerdefinierte Guzzle-Ausnahmen sie erweitern.

Dieser Ansatz kann in Anwendungsfällen nützlich sein, in denen Guzzle unter der Haube verwendet wird, wie in Laravel oder AWS API PHP SDK), damit Sie die echte Guzzle-Ausnahme nicht abfangen können.

In diesem Fall ist die Ausnahmeklasse möglicherweise nicht die in den Guzzle-Dokumenten genannte (z. B. GuzzleHttp\Exception\RequestException Als Stammausnahme für Guzzle).

Sie müssen also stattdessen \Exception Abfangen, aber denken Sie daran, dass es sich immer noch um die Instanz der Guzzle-Ausnahmeklasse handelt.

Trotzdem vorsichtig verwenden. Diese Wrapper können dazu führen, dass die ursprünglichen Methoden des Guzzle $e->getResponse() -Objekts nicht verfügbar sind. In diesem Fall müssen Sie sich den tatsächlichen Quellcode der Wrapper-Ausnahme ansehen und herausfinden, wie Sie den Status, die Meldung usw. abrufen können, anstatt die Methoden von Guzzle $response Zu verwenden.

Wenn Sie Guzzle direkt selbst anrufen, können Sie GuzzleHttp\Exception\RequestException Oder eine andere in deren Ausnahmedokumentation angegebene Angabe in Bezug auf Ihre Anwendungsfallbedingungen abfangen.

3
bob-12345