거즐의 예외 포착
개발 중인 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)
해서)\
동작하는지 확인합니다.
되어 있는 try
의 Exception
잡히지 않은 것을 잡는 것이어야 합니다.
테스트의 첫 번째 파트는 예외의 슬로우라고 생각하고, 그것을 다음 순서로 정리합니다.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
그 후 를 사용하여getResponse
400레벨의 에러를 확인하고, 거기서부터 계속합니다.
잡고 있었어요GuzzleHttp\Exception\BadResponseException
@dado가 제안하는 것처럼.하지만 어느 날 나는GuzzleHttp\Exception\ConnectException
도메인용 DNS를 사용할 수 없는 경우.그래서 내 제안은 - catchGuzzleHttp\Exception\ConnectException
DNS 에러로부터도 안전합니다.
최신 버전인 6^을 사용하고 있고 JSON 파라미터가 있는 경우,'http_errors' => false
아래 그림과 같이 어레이와 JSON을 조합하여
JSON이 있는 상태에서 이 작업을 하기 위해 먼 곳을 내다봤지만 정확한 답을 찾을 수 없었습니다.
언급URL : https://stackoverflow.com/questions/17658283/catching-exceptions-from-guzzle
'programing' 카테고리의 다른 글
"0을 제외한 모든 양의 정수"의 정규식은 무엇입니까? (0) | 2022.09.25 |
---|---|
Python의 '_enter__' 및 '_exit__' 설명 (0) | 2022.09.25 |
LAN에서 Debian 9(Stretch)의 MariaDB 10.1.23에 접속 (0) | 2022.09.25 |
소수점 두 자리 숫자 표시 (0) | 2022.09.25 |
MariaDB : 두 점 사이의 거리(km)를 계산합니다. (0) | 2022.09.25 |