Guzzle 6 - 承诺 - 捕捉异常

时间:2016-06-05 20:47:08

标签: php guzzle guzzle6

我真的不明白如何在onReject处理程序中捕获异常(转发它)。我想知道是否有人能指出我如何成功地做正确的方向。

我正在发送一些异步请求,当一个失败时遇到“遇到未捕获的异常 - 类型:GuzzleHttp \ Exception \ ClientException”它永远不会被捕获。

我读过:

但目前尚不清楚以下为什么不起作用。我的理解是当在onReject(RequestException)中抛出ClientException时,它会将其进一步推送到下一个onReject(ClientException)并被正确捕获。

任何帮助都将不胜感激。

$client = new GuzzleHttp\Client();

$promise = $client->requestAsync('POST', SOME_URL, [
  ... SOME_PARAMS ...
]);

$promise->then(
function (ResponseInterface $res) {
  //ok
},
function (RequestException $e) {
  //inside here throws a ClientException
}
)->then(null, function (ClientException $e) {
  //Why does it not get caught/forwarded to this error handler?
});

2 个答案:

答案 0 :(得分:2)

根据guzzle文档,

  
    

如果在$ onRejected回调中抛出异常,则会以抛出异常为原因调用后续的$ onRejected回调。

  

所以这应该有效:

$promise
->then(
    function (ResponseInterface $res) {
        // this will be called when the promise resolves
        return $someVal;
    },
    function (RequestException $e) {
        // this will be called when the promise resolving failed
        // if you want this to bubble down further the then-line, just re-throw:
        throw $e;
    }
)
->then(
    function ($someVal) {

    },
    function (RequestException $e) {
        // now the above thrown Exception should be passed in here
    });

答案 1 :(得分:1)

Guzzle承诺 follow 承诺/ A + 标准。因此,我们可以依靠official description来掌握您对此感到好奇的行为:

  

2.2.7.1.如果onFulfilled或onRejected返回值x,请运行承诺解决程序[[Resolve]](promise2, x)

     

2.2.7.2.如果onFulfilledonRejected引发异常e,则必须拒绝promise2 e作为原因。

后来针对 2.2.7.2 案例:

  

2.3.2.如果x是承诺,则采用其状态

因此,您可以按照@lkoell提出的解决方案或从回调中返回RejectedPromise,这会强制后续承诺采用rejected状态。

$promiseA = $promise
    ->then(
        function (ResponseInterface $res) {
          //ok
        },
        function (RequestException $e) {
          //This will force $promiseB adopt $promiseC state and get rejected
          return $promiseC = new RejectedPromise($clientException);
        }
);
$promiseB = $promiseA->then(null, function (ClientException $e) {
          // There you will get rejection
});

这种方式更灵活,因为您可以拒绝承诺,不仅有异常,还有任何理由(承诺除外)。