Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GuzzleHttp Asynchronous Request Exception

Tags:

php

guzzle

I can't figure out how I can throw an exception from Guzzle future response handler. Here's my code:

<?php
require 'vendor/autoload.php';

$client = new \GuzzleHttp\Client();

$req = $client->createRequest('GET', 'http://www.google.com', array(
    'future' => true,
));
echo "Sending request\n";
$response = $client->send($req);

try {
    $response->then(function ($data) {
        echo "Response is received\n";
        throw new Exception('Test');
    })->then(function () {
        // success handler
    }, function (Exception $exception) {
        echo "Error handler invoked\n";
        throw $exception;
    });
} catch (Exception $e) {
    echo "Exception catched\n";
}
echo "Finish\n";

The catch block is never reached in this case.

like image 345
Alexey Kosov Avatar asked Oct 28 '14 08:10

Alexey Kosov


People also ask

Is guzzle asynchronous?

Guzzle allows you to send both asynchronous and synchronous requests using the same interface and no direct dependency on an event loop. This flexibility allows Guzzle to send an HTTP request using the most appropriate HTTP handler based on the request being sent.

How do I send a POST request with GuzzleHttp?

Sending Requests You can create a request and then send the request with the client when you're ready: use GuzzleHttp\Psr7\Request; $request = new Request('PUT', 'http://httpbin.org/put'); $response = $client->send($request, ['timeout' => 2]);

How do I debug guzzle request?

Debugging when using Guzzle, is quiet easy by providing the debug key in the payload: $client->request('GET', '/url, ['debug' => true]); This is quiet easy and not an issue if your are not passing any body content, using only query string to dump what's been request.

What is GuzzleHttp?

Guzzle is a PHP HTTP client that makes it easy to send HTTP requests and trivial to integrate with web services. Simple interface for building query strings, POST requests, streaming large uploads, streaming large downloads, using HTTP cookies, uploading JSON data, etc...


1 Answers

You are working with promises when using asynchronous Guzzle requests. Using the then() function off of a FutureResponse will create a promise that is fulfilled or rejected when the request completes. If an error occurs while sending, the promise is rejected, which means the second callback provided to the then function is invoked. When a request completes successfully, it is resolved, and the first callback provided to the then function is invoked. When an exception is thrown in any of the promise functions, the exception is caught inside of the promise and forwarded to the next error handler in the chain. In your example, if the request succeeds, then you throw an exception which will trigger the error callback. Throwing an exception in the error callback will either forward the exception to the next error callback in the promise chain, or silently eat the error (in your case, there are no further error callbacks to trigger).

The React Promises library that is used by Guzzle has more documentation on resolution and rejection forwarding of promises: https://github.com/reactphp/promise#how-promise-forwarding-works. The author of this library is looking into adding a done() function that can be used as a terminal promise handler that actually throws unhandled exceptions.

like image 130
Michael Dowling Avatar answered Oct 21 '22 05:10

Michael Dowling