【问题标题】:Guzzle 6 - Promises - Catching ExceptionsGuzzle 6 - 承诺 - 捕捉异常
【发布时间】:2016-10-05 10:06:57
【问题描述】:

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

【问题讨论】:

  • 你真的解决了这个问题吗?,我被困在同一件事上,这让我怀疑异步请求可能不是真正异步的?,因为当你运行你的发送异步请求的代码段,因为它是异步的...

标签: php guzzle guzzle6


【解决方案1】:

Guzzle Promises follow Promises/A+ 标准。因此,我们可以依靠official description 来掌握您感兴趣的行为:

2.2.7.1. 如果 onFulfilled 或 onRejected 返回值 x,则运行 Promise Resolution Procedure [[Resolve]](promise2, x)

2.2.7.2. 如果onFulfilledonRejected 抛出异常e,则必须以e 为理由拒绝promise2

以后对于 2.2.7.2 的情况:

2.3.2. 如果x 是一个promise,采用它的状态

因此,您可以遵循@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
});

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

【讨论】:

    【解决方案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
        });
    

    【讨论】:

    • 这是正确答案,应该标记为解决方案!
    猜你喜欢
    • 2017-03-27
    • 2019-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 1970-01-01
    • 2020-04-20
    相关资源
    最近更新 更多