Catching exceptions from Guzzle
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.