developer tip

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

optionbox 2020. 8. 21. 07:33
반응형

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

전달 true받는 getBody기능을 사용하면 문자열로 응답 본문을 얻고 싶은 것을 나타냅니다. 그렇지 않으면 클래스의 인스턴스로 가져옵니다 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은 BadRequestException의 수퍼 클래스이기도합니다. 이것은 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 = 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.
     * 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()); // 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. You get the response's information in conveniently separated items.

Side Notes:

With catch clause we catch the inheritance chain PHP root exception class \Exception as Guzzle custom exceptions extend it.

This approach may be useful for use cases where Guzzle is used under the hood like in Laravel or AWS API PHP SDK so you cannot catch the genuine Guzzle exception.

In this case, the exception class may not be the one mentioned in the Guzzle docs (e.g. GuzzleHttp\Exception\RequestException as the root exception for Guzzle).

So you have to catch \Exception instead but bear in mind it is still the Guzzle exception class instance.

Though use with care. Those wrappers may make Guzzle $e->getResponse() object's genuine methods not available. In this case, you will have to look at the wrapper's actual exception source code and find out how to get status, message, etc. instead of using Guzzle $response's methods.

If you call Guzzle directly yourself you can catch GuzzleHttp\Exception\RequestException or any other one mentioned in their exceptions docs with respect to your use case conditions.

참고URL : https://stackoverflow.com/questions/19748105/handle-guzzle-exception-and-get-http-body

반응형