[php] Guzzle 예외 처리 및 HTTP 본문 가져 오기

서버가 4xx 및 5xx 상태 코드를 반환 할 때 Guzzle의 오류를 처리하고 싶습니다. 다음과 같이 요청합니다.

$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코드 정보를 반환하지만 HTTP 응답의 본문은 반환하지 않습니다. 응답 본문은 어떻게받을 수 있습니까?



답변

Guzzle 3.x

워드 프로세서 , 당신은 (적절한 예외 유형 잡을 수 ClientErrorResponseException4XX 오류)를하고 전화 getResponse()응답 개체를 얻을 수있는 방법을 다음 호출 getBody()것을에 :

use Guzzle\Http\Exception\ClientErrorResponseException;

...

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

함수에 전달 하면 응답 본문을 문자열로 가져 오려고 함 truegetBody나타냅니다. 그렇지 않으면 클래스의 인스턴스로 얻을 수 있습니다 Guzzle\Http\EntityBody.


답변

Guzzle 6.x

워드 프로세서 , 당신은 캐치해야 할 수도 예외 유형은 다음과 같습니다

  • GuzzleHttp\Exception\ClientException 400 수준 오류
  • GuzzleHttp\Exception\ServerException 500 수준 오류
  • GuzzleHttp\Exception\BadResponseException 둘 다 (그들의 수퍼 클래스입니다)

따라서 이러한 오류를 처리하는 코드는 다음과 같습니다.

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


답변

위의 답변은 좋지만 네트워크 오류를 포착하지 않습니다. Mark가 언급했듯이 BadResponseException은 ClientException 및 ServerException의 수퍼 클래스입니다. 그러나 RequestException은 BadResponseException의 수퍼 클래스이기도합니다. RequestException은 400 및 500 오류뿐만 아니라 네트워크 오류 및 무한 리디렉션에도 발생합니다. 따라서 아래 페이지를 요청했지만 네트워크가 재생 중이고 캐치가 BadResponseException 만 기대한다고 가정 해 보겠습니다. 응용 프로그램에서 오류가 발생합니다.

이 경우 RequestException을 예상하고 응답을 확인하는 것이 좋습니다.

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

}


답변

2019 년 기준으로 예외를 처리하고 응답 본문, 상태 코드, 메시지 및 기타 유용한 응답 항목을 가져 오기 위해 위의 답변과 Guzzle 문서 에서 정교하게 설명한 내용이 있습니다.

try {
    /**
     * We use Guzzle to make an HTTP request somewhere in the
     * following theMethodMayThrowException().
     */
    $result = theMethodMayThrowException();
} catch (\GuzzleHttp\Exception\RequestException $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.
     * Just check the exception object has the response before.
     */
    if ($e->hasResponse()) {
        $response = $e->getResponse();
        var_dump($response->getStatusCode()); // HTTP status code;
        var_dump($response->getReasonPhrase()); // Response message;
        var_dump((string) $response->getBody()); // Body, normally it is JSON;
        var_dump(json_decode((string) $response->getBody())); // Body as the decoded JSON;
        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. ...

짜잔. 편리하게 구분 된 항목으로 응답 정보를 얻을 수 있습니다.

사이드 노트 :

함께 catch절 우리는 상속 체인 PHP 루트 예외 클래스를 잡을
\Exception목구멍 사용자 정의 예외를 확장한다.

이 접근 방식은 Guzzle이 Laravel 또는 AWS API PHP SDK와 같이 내부적으로 사용되는 사용 사례에 유용 할 수 있으므로 진정한 Guzzle 예외를 포착 할 수 없습니다.

이 경우 예외 클래스는 Guzzle 문서에 언급 된 클래스가 아닐 수 있습니다 (예 : Guzzle GuzzleHttp\Exception\RequestException의 루트 예외).

따라서 \Exception대신 잡아야 하지만 여전히 Guzzle 예외 클래스 인스턴스임을 명심해야합니다.

조심해서 사용하십시오. 이러한 래퍼로 인해 Guzzle $e->getResponse()개체의 정품 메서드를 사용할 수 없게 될 수 있습니다. 이 경우, Guzzle $response의 메소드 를 사용하는 대신 래퍼의 실제 예외 소스 코드를보고 상태, 메시지 등을 얻는 방법을 찾아야 합니다.

Guzzle을 직접 직접 호출하면 사용 사례 조건과 관련하여 예외 문서에GuzzleHttp\Exception\RequestException 언급 된 다른 것을 잡을 수 있습니다 .


답변

'http_errors' => falseguzzle 요청 옵션을 넣으면 다음과 같이 4xx 또는 5xx 오류가 발생하는 동안 예외 발생을 중지합니다.$client->get(url, ['http_errors' => false]) 합니다. 그런 다음 응답을 구문 분석합니다. 정상이든 오류이든 상관없이
더 많은 정보를 얻을 수 있습니다.


답변