Catching exceptions from Guzzle

我只是一个虾纸丫 提交于 2019-11-27 17:29:32

If the Exception is being thrown in that try block then at worst case scenario Exception should be catching anything uncaught.

Consider that the first part of the test is throwing the Exception and wrap that in the try block as well.

Depending on your project, disabling exceptions for guzzle might be necessary. Sometimes coding rules disallow exceptions for flow control. You can disable exceptions for Guzzle 3 like this:

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

This does not disable curl exceptions for something like timeouts, but now you can get every status code easily:

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

To check, if you got a valid code, you can use something like this:

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

... or better handle all expected codes:

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

For Guzzle 5.3

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

Thanks to @mika

For Guzzle 6

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

To catch Guzzle errors you can do something like this:

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

... but, to be able to "log" or "resend" your request try something like this:

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

});

... or if you want to "stop event propagation" you can overridde event listener (with a higher priority than -255) and simply stop event propagation.

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

thats a good idea to prevent guzzle errors like:

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

in your application.

In my case I was throwing Exception on a namespaced file, so php tried to catch My\Namespace\Exception therefore not catching any exceptions at all.

Worth checking if catch (Exception $e) is finding the right Exception class.

Just try catch (\Exception $e) (with that \ there) and see if it works.

You need to add a extra parameter with http_errors => false

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

Old question, but Guzzle adds the response within the exception object. So a simple try-catch on GuzzleHttp\Exception\ClientException and then using getResponse on that exception to see what 400-level error and continuing from there.

I was catching GuzzleHttp\Exception\BadResponseException as @dado is suggesting. But one day I got GuzzleHttp\Exception\ConnectException when DNS for domain wasn't available. So my suggestion is - catch GuzzleHttp\Exception\ConnectException to be safe about DNS errors as well.

    try {

    } catch (GuzzleHttp\Subscriber\HttpError $e) {
        //catches all 4xx and 5xx status codes
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!