programing

Guzzle 예외를 처리하고 HTTP 본문을 가져옵니다.

kingscode 2022. 11. 8. 21:20
반응형

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 응답 본문은 반환하지 않습니다.대응 본문을 입수하려면 어떻게 해야 하나요?

거즐 6.x

문서에 따라 잡아야 할 예외 유형은 다음과 같습니다.

  • GuzzleHttp\Exception\ClientException
  • GuzzleHttp\Exception\ServerException
  • 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();
}

거즐 3.x

문서에 따라 적절한 예외 유형을 파악할 수 있습니다(ClientErrorResponseException 오류)및 4xx 오류)를 호출합니다.getResponse()오브젝트를 메서드를 사용하여 호출합니다.getBody()에 대해서 「」를 참조해 주세요.

use Guzzle\Http\Exception\ClientErrorResponseException;

...

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

★★true이 함수는 응답 본문을 문자열로 가져오는 것을 나타냅니다.그렇지 않으면 클래스의 인스턴스로 가져옵니다.Guzzle\Http\EntityBody.

상기의 회답은 양호하지만, 네트워크 에러는 검출되지 않습니다.Mark가 언급했듯이 BadResponseException은 ClientException 및 ServerException의 슈퍼 클래스일 뿐입니다.단, 요청예외는 BadResponseException의 슈퍼 클래스이기도 합니다.부탁한다400 및 500 오류뿐만 아니라 네트워크 오류 및 무한 리다이렉트에도 예외가 발생합니다.예를 들어, 아래 페이지를 요청했지만 네트워크가 제대로 작동하지 않고 BadResponseException만 발생한다고 가정해 보겠습니다.응용 프로그램이 오류를 발생시킵니다.

이 경우 요청을 기대하는 것이 좋습니다.예외 및 응답을 확인합니다.

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 docs에서 예외 처리, 응답 본문, 상태 코드, 메시지 및 기타 귀중한 응답 아이템을 얻기 위해 상세하게 설명하였습니다.

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. ...

Voila. 응답 정보는 쉽게 구분된 항목으로 얻을 수 있습니다.

사이드 노트:

★★★★★★★★★★★★★★★★ catch 예외 클래스 php를 합니다.\Exception이치노

이 접근법은 Laravel이나 AWS API PHP SDK처럼 Guzzle이 후드 아래에서 사용되기 때문에 Guzzle의 실제 예외를 포착할 수 없는 경우에 도움이 될 수 있습니다.

이되어 있는 수 "Guzle" "Guzle" "Guzle" "Guzle" "Guzle" "Guzle" "Guzle" "Guzzle" "Guzzze" "Guzzle" "Guzzuzzzzz").GuzzleHttp\Exception\RequestException구즐의 근본적인 예외로 간주됩니다.)

꼭 해요.\Exception대신, 여전히 Guzzle 예외 클래스의 인스턴스라는 것을 기억하십시오.

의해주은 구즐을 수 .$e->getResponse()개체의 정규 메서드를 사용할 수 없습니다.래퍼의 를 보고 Guzle을 상태,얻는 .$response의 메서드.

하면 잡을 수 .GuzzleHttp\Exception\RequestException또는 예외 문서에 기재되어 있는 사용 사례 조건에 관한 기타 정보입니다.

고고 put put 'http_errors' => false에서는 guzle 에러가 했을 때 guzle 4xx 또는 5xx 에러는 다음과 .$client->get(url, ['http_errors' => false])그 후 응답을 해석합니다.정상인지 오류인지에 관계없이 자세한 내용은 응답에 있습니다.

질문은 다음과 같습니다.

서버가 4xx 및 5xx 상태 코드를 반환할 때 Guzle에서 오류를 처리하고 싶습니다.

4xx 또는 5xx 상태 코드를 구체적으로 처리할 수 있지만 실제로는 모든 예외를 파악하고 그에 따라 결과를 처리하는 것이 좋습니다.

문제는 실수를 처리하고 싶은지, 아니면 본체를 입수하고 싶은지 여부입니다.대부분의 경우 오류를 처리하고 메시지 본문을 얻지 않거나 오류가 없는 경우에만 본문을 얻는 것으로 충분하다고 생각합니다.

이것은 변경될 수 있기 때문에 사용하시는 버전의 Guzzle이 어떻게 처리되는지 확인하기 위해 문서를 봅니다.https://docs.guzzlephp.org/en/stable/quickstart.html#exceptions

,에러에 관한 작업의 공식 메뉴얼의 이 페이지를 참조해 주세요.이 문서는 다음과 같습니다.

또는 는 4xx "5x " 를 .Guzzle\Http\Exception\BadResponseException구체적으로는 4xx 에러에 의해,Guzzle\Http\Exception\ClientErrorResponseException, 및 5xx 오류는 Guzle을 발생시킵니다.\Http\Exception\ServerErrorResponseException. 특정 도 있고, 수도 BadResponseException어떤 유형의 오류에도 대처할 수 있습니다.

Guzzle 7(문서로부터):

. \RuntimeException
└── TransferException (implements GuzzleException)
    └── RequestException
        ├── BadResponseException
        │   ├── ServerException
        │   └── ClientException
        ├── ConnectException
        └── TooManyRedirectsException

따라서 코드는 다음과 같습니다.

try {
    $response = $client->request('GET', $url);
    if ($response->getStatusCode() >= 300) {
       // is HTTP status code (for non-exceptions) 
       $statusCode = $response->getStatusCode();
       // handle error 
    } else {
      // is valid URL
    }
            
} catch (TooManyRedirectsException $e) {
    // handle too many redirects
} catch (ClientException | ServerException $e) {
    // ClientException - A GuzzleHttp\Exception\ClientException is thrown for 400 level errors if the http_errors request option is set to true.
    // ServerException - A GuzzleHttp\Exception\ServerException is thrown for 500 level errors if the http_errors request option is set to true.
    if ($e->hasResponse()) {
       // is HTTP status code, e.g. 500 
       $statusCode = $e->getResponse()->getStatusCode();
    }
} catch (ConnectException $e) {
    // ConnectException - A GuzzleHttp\Exception\ConnectException exception is thrown in the event of a networking error. This may be any libcurl error, including certificate problems
    $handlerContext = $e->getHandlerContext();
    if ($handlerContext['errno'] ?? 0) {
       // this is the libcurl error code, not the HTTP status code!!!
       // for example 6 for "Couldn't resolve host"
       $errno = (int)($handlerContext['errno']);
    } 
    // get a description of the error (which will include a link to libcurl page)
    $errorMessage = $handlerContext['error'] ?? $e->getMessage();
         
} catch (\Exception $e) {
    // fallback, in case of other exception
}

본문이 정말로 필요한 경우, 평상시와 같이 검색할 수 있습니다.

https://docs.guzzlephp.org/en/stable/quickstart.html#using-responses

$body = $response->getBody();

본문은 없지만 설명 텍스트가 있는 오류에 대해서는 위의 응답 중 어느 것도 작동하지 않습니다.는는 for for for for for for 。SSL certificate problem: unable to get local issuer certificate에러입니다.그래서 코드를 바로 조사했습니다.닥터가 별로 말을 하지 않아서 (Guzzle 7.1에서) 이렇게 했습니다.

try {
    // call here
} catch (\GuzzleHttp\Exception\RequestException $e) {
    if ($e->hasResponse()) {
        $response = $e->getResponse();
        // message is in $response->getReasonPhrase()
    } else {
        $response = $e->getHandlerContext();
        if (isset($response['error'])) {
            // message is in $response['error']
        } else {
            // Unknown error occured!
        }
    }
}

예외는 getResponse 메서드를 가진 BadResponseException 인스턴스여야 합니다.그런 다음 응답 본문을 문자열에 캐스팅할 수 있습니다.참고 자료: https://github.com/guzzle/guzzle/issues/1105

use GuzzleHttp\Exception\BadResponseException;

$url = $this->baseUrl . "subnet?section=$section";
try {
    $response = $this->client->get($url);
    $subnets = json_decode($response->getBody(), true);
    return $subnets['subnets'];
} catch (BadResponseException $ex) {
    $response = $ex->getResponse();
    $jsonBody = (string) $response->getBody();
    // do something with json string...
}

저는 Laravel 패키지 안에서 Guzle과 함께 작업을 했습니다.

try {
    $response = $this->client->get($url);
}
catch(\Exception $e) {
    $error = $e->getResponse();
    dd($error);
}

전체 오류 메시지를 얻을 수 있습니다(잘라지지 않음).다음 코드를 사용해 보십시오.

try {
    ...
} catch (GuzzleHttp\Exception\RequestException $e) {
    $error = \GuzzleHttp\Psr7\str($e->getResponse());
    print_r($error);
}

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

반응형