8

我真的不明白如何在 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?
});
4

2 回答 2

4

根据 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
    });
于 2017-11-28T14:53:50.707 回答
2

Guzzle Promises 遵循 Promises/A+标准。因此我们可以依靠官方的描述来掌握你好奇的行为:

2.2.7.1。如果 onFulfilled 或 onRejected 返回一个值x,则运行 Promise Resolution Procedure [[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
});

这种方式更灵活,因为您不仅可以拒绝一个承诺,而且可以拒绝任何理由(除了承诺)。

于 2017-12-28T17:44:13.807 回答