Исключение асинхронного запроса GuzzleHttp

Я не могу понять, как я могу создать исключение из обработчика Guzzle future response. Вот мой код:

<?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";

В этом случае блок catch никогда не достигается.


person Alexey Kosov    schedule 28.10.2014    source источник


Ответы (2)


Вы работаете с промисами при использовании асинхронных запросов Guzzle. Использование функции then() вне функции FutureResponse создаст обещание, которое будет выполнено или отклонено после завершения запроса. Если при отправке возникает ошибка, обещание отклоняется, что означает, что вызывается второй обратный вызов, предоставленный функции then. Когда запрос завершается успешно, он разрешается, и вызывается первый обратный вызов, предоставленный функции then. Когда в любой из функций промиса возникает исключение, оно перехватывается внутри промиса и пересылается следующему обработчику ошибок в цепочке. В вашем примере, если запрос выполнен успешно, вы создаете исключение, которое вызывает обратный вызов ошибки. Выброс исключения в обратном вызове ошибки либо перенаправит исключение на следующий обратный вызов ошибки в цепочке обещаний, либо молча съест ошибку (в вашем случае больше нет обратных вызовов ошибок для запуска).

В библиотеке React Promises, используемой Guzzle, есть дополнительная документация по разрешению и отклонению пересылки промисов: https://github.com/reactphp/promise#how-promise-forwarding-works. Автор этой библиотеки рассматривает возможность добавления функции done(), которую можно использовать в качестве обработчика обещаний терминала, который фактически выдает необработанные исключения.

person Michael Dowling    schedule 28.10.2014
comment
@MichaelDowling GuzzleHttp\Promises все еще ест исключения? - person Jory Geerts; 30.12.2016

Асинхронность означает, что ваш скрипт не будет ждать ответа от сервера, а просто отправит запрос и продолжит выполнение. В этом случае сценарий завершает свою жизнь до того, как возвращается ответ, поэтому ни один из обратных вызовов никогда не выполняется.

Добавьте эту строку после catch, чтобы заблокировать выполнение сценария до тех пор, пока не вернется ответ.

$response->getStatusCode(); 

Если вы предоставите больше информации о том, чего хотите достичь, мы сможем помочь вам в дальнейшем.

person motanelu    schedule 28.10.2014