開発中のAPIで実行している一連のテストから例外をキャッチしようとしています。APIメソッドを使用するためにGuzzleを使用しています。テストをtry/catchブロックにラップしましたが、未処理の例外エラーが引き続き発生しています。ドキュメントに記載されているイベントリスナーを追加しても、何も実行されないようです。 500、401、400のHTTPコードを持つ応答を取得できるようにする必要があります。実際には、システムが機能しなかった場合、システムは呼び出しの結果に基づいて最も適切なコードを設定するため、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;
}
スローされた例外タイプの特定のcatchブロックを使用しても、まだ戻ってきています
Fatal error: Uncaught exception 'Guzzle\Http\Exception\ClientErrorResponseException' with message 'Client error response [status code] 401 [reason phrase] Unauthorized [url]
予想どおり、ページ上のすべての実行が停止します。 BadResponseExceptionキャッチの追加により、404を正しくキャッチできましたが、これは500または401の応答では機能しないようです。誰でも私が間違っているところを教えてください。
そのtry
ブロックで例外がスローされている場合、最悪の場合、シナリオException
はキャッチされていないものをキャッチします。
テストの最初の部分が例外をスローすることを考慮し、それをtry
ブロックでラップします。
プロジェクトによっては、ガズルの例外を無効にする必要がある場合があります。コーディング規則では、フロー制御の例外が許可されない場合があります。例外を無効にすることができますGuzzle 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に感謝
Guzzle 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より高い優先度で)、イベントの伝播を停止することができます。
$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
を投げていたので、phpはMy\Namespace\Exception
をキャッチしようとしたため、例外はまったくキャッチしませんでした。
catch (Exception $e)
が正しいException
クラスを見つけているかどうかを確認する価値があります。
catch (\Exception $e)
(その\
がある)を試して、それが機能するかどうかを確認してください。
Http_errors => falseのパラメーターを追加する必要があります
$request = $client->get($url, ['http_errors' => false]);
古い質問ですが、Guzzleは例外オブジェクト内に応答を追加します。したがって、GuzzleHttp\Exception\ClientException
で単純なtry-catchを実行し、その例外でgetResponse
を使用して、400レベルのエラーを確認し、そこから続行します。
@dadoが示唆しているように、GuzzleHttp\Exception\BadResponseException
をキャッチしていました。しかし、ある日、ドメインのDNSが利用できないときにGuzzleHttp\Exception\ConnectException
を受け取りました。したがって、私の提案は-GuzzleHttp\Exception\ConnectException
をキャッチして、DNSエラーについても安全であるようにすることです。