programing

거즐의 예외 포착

goodcopy 2022. 9. 25. 23:04
반응형

거즐의 예외 포착

개발 중인 API에서 실행 중인 일련의 테스트에서 예외를 포착하기 위해 Guzzle을 사용하여 API 메서드를 사용하고 있습니다.테스트를 시도/캐치 블록으로 포장했는데도 처리되지 않은 예외 오류가 발생합니다.문서에 기술된 이벤트청취자를 추가하는 것은 아무런 효과가 없는 것 같습니다.HTTP 코드가 500, 401, 400인 응답을 취득할 수 있어야 합니다.실제로 200이 아닌 것은, 시스템이 동작하지 않는 경우, 콜의 결과에 근거해 가장 적절한 코드를 설정하기 때문입니다.

현재 코드 예시

foreach($tests as $test){

        $client = new Client($api_url);
        $client->getEventDispatcher()->addListener('request.error', function(Event $event) {        

            if ($event['response']->getStatusCode() == 401) {
                $newResponse = new Response($event['response']->getStatusCode());
                $event['response'] = $newResponse;
                $event->stopPropagation();
            }            
        });

        try {

            $client->setDefaultOption('query', $query_string);
            $request = $client->get($api_version . $test['method'], array(), isset($test['query'])?$test['query']:array());


          // Do something with Guzzle.
            $response = $request->send();   
            displayTest($request, $response);
        }
        catch (Guzzle\Http\Exception\ClientErrorResponseException $e) {

            $req = $e->getRequest();
            $resp =$e->getResponse();
            displayTest($req,$resp);
        }
        catch (Guzzle\Http\Exception\ServerErrorResponseException $e) {

            $req = $e->getRequest();
            $resp =$e->getResponse();
            displayTest($req,$resp);
        }
        catch (Guzzle\Http\Exception\BadResponseException $e) {

            $req = $e->getRequest();
            $resp =$e->getResponse();
            displayTest($req,$resp);
        }
        catch( Exception $e){
            echo "AGH!";
        }

        unset($client);
        $client=null;

    }

던져진 예외 유형에 대한 특정 캐치 블록이 있더라도 여전히 반환됩니다.

Fatal error: Uncaught exception 'Guzzle\Http\Exception\ClientErrorResponseException' with message 'Client error response [status code] 401 [reason phrase] Unauthorized [url]

페이지상의 모든 실행이 정지됩니다.BadResponseException catch를 추가하여 404를 정확하게 잡을 수 있었지만, 500 또는 401개의 응답에서는 작동하지 않는 것 같습니다.제가 어디가 잘못됐는지 누가 좀 알려주세요.

프로젝트에 따라서는, 거즐의 예외를 무효로 할 필요가 있는 경우가 있습니다.코딩 규칙에 따라 흐름 제어 예외가 허용되지 않을 수 있습니다.다음과 같이 Guzle 3의 예외를 비활성화할 수 있습니다.

$client = new \Guzzle\Http\Client($httpBase, array(
  'request.options' => array(
     'exceptions' => false,
   )
));

이것은 타임아웃과 같은 경우에 컬 예외를 무효로 하는 것은 아니지만, 이제 모든 상태 코드를 쉽게 얻을 수 있습니다.

$request = $client->get($uri);
$response = $request->send();
$statuscode = $response->getStatusCode();

유효한 코드가 있는 경우는, 다음과 같이 확인할 수 있습니다.

if ($statuscode > 300) {
  // Do some error handling
}

... 또는 예상되는 모든 코드를 더 잘 처리합니다.

if (200 === $statuscode) {
  // Do something
}
elseif (304 === $statuscode) {
  // Nothing to do
}
elseif (404 === $statuscode) {
  // Clean up DB or something like this
}
else {
  throw new MyException("Invalid response from api...");
}

Guzzle 5.3의 경우

$client = new \GuzzleHttp\Client(['defaults' => [ 'exceptions' => false ]] );

@mika 덕분에

거즐 6의 경우

$client = new \GuzzleHttp\Client(['http_errors' => false]);

Guzzle 오류를 감지하려면 다음과 같이 하십시오.

try {
    $response = $client->get('/not_found.xml')->send();
} catch (Guzzle\Http\Exception\BadResponseException $e) {
    echo 'Uh oh! ' . $e->getMessage();
}

... 단, 요청을 "로그" 또는 "로그"하려면 다음과 같이 하십시오.

// Add custom error handling to any request created by this client
$client->getEventDispatcher()->addListener(
    'request.error', 
    function(Event $event) {

        //write log here ...

        if ($event['response']->getStatusCode() == 401) {

            // create new token and resend your request...
            $newRequest = $event['request']->clone();
            $newRequest->setHeader('X-Auth-Header', MyApplication::getNewAuthToken());
            $newResponse = $newRequest->send();

            // Set the response object of the request without firing more events
            $event['response'] = $newResponse;

            // You can also change the response and fire the normal chain of
            // events by calling $event['request']->setResponse($newResponse);

            // Stop other events from firing when you override 401 responses
            $event->stopPropagation();
        }

});

이벤트 전파를 정지하는 경우는 이벤트청취자(-255보다 높은 priority)를 덮어쓰고 이벤트 전파를 정지합니다.

$client->getEventDispatcher()->addListener('request.error', function(Event $event) {
if ($event['response']->getStatusCode() != 200) {
        // Stop other events from firing when you get stytus-code != 200
        $event->stopPropagation();
    }
});

이는 다음과 같은 오류를 방지하기 위한 좋은 방법입니다.

request.CRITICAL: Uncaught PHP Exception Guzzle\Http\Exception\ClientErrorResponseException: "Client error response

를 참조해 주세요.

에는 던지고 요.Exception는 namesched라는 이름의 php를 잡으려고 .My\Namespace\Exception예외는 전혀 포착하지 못했습니다.

할 가 있다catch (Exception $e) 것을 입니다.Exception

한번 해보세요.catch (\Exception $e) 해서)\동작하는지 확인합니다.

되어 있는 tryException잡히지 않은 것을 잡는 것이어야 합니다.

테스트의 첫 번째 파트는 예외의 슬로우라고 생각하고, 그것을 다음 순서로 정리합니다.try블록도 마찬가지입니다.

http_parameter => false를 사용하여 파라미터를 추가해야 합니다.

$request = $client->get($url, ['http_errors' => false]);

Psr-7 Guzzle, Guzzle7 및 HTTP Client(laravel이 제공하는 Guzzle HTTP 클라이언트 주변의 표현 가능한 최소 API)에서 예외 처리에 대한 답변을 업데이트하고 싶습니다.

Guzle7 (Guzle6도 마찬가지)

요청 사용예외, 요청예외는 요청 전송 중에 발생할 수 있는 예외를 포착합니다.

try{
  $client = new \GuzzleHttp\Client(['headers' => ['Authorization' => 'Bearer ' . $token]]);
  
  $guzzleResponse = $client->get('/foobar');
  // or can use
  // $guzzleResponse = $client->request('GET', '/foobar')
    if ($guzzleResponse->getStatusCode() == 200) {
         $response = json_decode($guzzleResponse->getBody(),true);
         //perform your action with $response 
    } 
}
catch(\GuzzleHttp\Exception\RequestException $e){
   // you can catch here 400 response errors and 500 response errors
   // You can either use logs here use Illuminate\Support\Facades\Log;
   $error['error'] = $e->getMessage();
   $error['request'] = $e->getRequest();
   if($e->hasResponse()){
       if ($e->getResponse()->getStatusCode() == '400'){
           $error['response'] = $e->getResponse(); 
       }
   }
   Log::error('Error occurred in get request.', ['error' => $error]);
}catch(Exception $e){
   //other errors 
}

PSr7 거즐

use GuzzleHttp\Psr7;
use GuzzleHttp\Exception\RequestException;

try {
    $client->request('GET', '/foo');
} catch (RequestException $e) {
    $error['error'] = $e->getMessage();
    $error['request'] = Psr7\Message::toString($e->getRequest());
    if ($e->hasResponse()) {
        $error['response'] = Psr7\Message::toString($e->getResponse());
    }
    Log::error('Error occurred in get request.', ['error' => $error]);
}

HTTP Client의 경우

use Illuminate\Support\Facades\Http;
try{
    $response = Http::get('http://api.foo.com');
    if($response->successful()){
        $reply = $response->json();
    }
    if($response->failed()){
        if($response->clientError()){
            //catch all 400 exceptions
            Log::debug('client Error occurred in get request.');
            $response->throw();
        }
        if($response->serverError()){
            //catch all 500 exceptions
            Log::debug('server Error occurred in get request.');
            $response->throw();
        }
        
    }
 }catch(Exception $e){
     //catch the exception here
 }

오래된 질문이지만 Guzle은 예외 객체 내에 응답을 추가합니다.그래서 간단한 시운전을 해보겠습니다.GuzzleHttp\Exception\ClientException그 후 를 사용하여getResponse400레벨의 에러를 확인하고, 거기서부터 계속합니다.

잡고 있었어요GuzzleHttp\Exception\BadResponseException@dado가 제안하는 것처럼.하지만 어느 날 나는GuzzleHttp\Exception\ConnectException도메인용 DNS를 사용할 수 없는 경우.그래서 내 제안은 - catchGuzzleHttp\Exception\ConnectExceptionDNS 에러로부터도 안전합니다.

최신 버전인 6^을 사용하고 있고 JSON 파라미터가 있는 경우,'http_errors' => false아래 그림과 같이 어레이와 JSON을 조합하여

JSON이 있는 상태에서 이 작업을 하기 위해 먼 곳을 내다봤지만 정확한 답을 찾을 수 없었습니다.

언급URL : https://stackoverflow.com/questions/17658283/catching-exceptions-from-guzzle

반응형