繁体   English   中英

用抛出的异常打破承诺链

[英]Breaking promise chain with thrown exception

当前,如果在asyncFunction1()的 promise 回调中捕获到错误,应用程序将正确抛出“问题 A”异常。 然而,这是通过承诺链传递的,应用程序最终会看到“问题 B”,这意味着应用程序向用户显示了错误的错误。

我实际上需要中止执行并在抛出相关错误的同时中断链。 我怎样才能做到这一点?

可以在此处找到 HttpsError 类信息: https ://firebase.google.com/docs/reference/functions/functions.https.HttpsError

它明确提到:

确保在函数的顶层而不是从回调中抛出此异常,因为这不一定会因此异常而终止函数。

我似乎陷入了这个陷阱,但不知道如何解决它。 如果有人可以帮助我重构代码,以便我可以有效地捕获和正确处理这些错误,那将不胜感激。

exports.charge = functions.https.onCall(data => {
  asyncFunction1()
    .then(() => {
      asyncFunction2();
    })
    .catch((err) => {
      throw new functions.https.HttpsError(
        'not-found',
        'Problem A'
      );
    })
    .then(() => {
      asyncFunction3();
    })
    .catch((err) => {
      throw new functions.https.HttpsError(
        'not-found',
        'Problem B'
      );
    })
});

有许多不同的方法可以解决这个问题:

  1. 您可以让每个异步函数在拒绝时设置适当的错误,这样您就不必在自己的.catch()手动添加正确的错误。

  2. 您可以在最后一个.catch()测试以查看是否已经设置了适当的错误,如果是,则重新抛出它,而不是用另一个错误覆盖它。

  3. 您可以将最后一个.catch()直接放在asyncFunction3()调用上,而不是像这样放在整个链上,因此您只针对该函数的拒绝使用该错误代码:

修改后的代码:

exports.charge = functions.https.onCall(data => {
    return asyncFunction1().then(() => {
        return asyncFunction2();
    }).catch((err) => {
        // set appropriate error for rejection in either of the first two async functions
        throw new functions.https.HttpsError('not-found', 'Problem A');
    }).then(() => {
        return asyncFunction3().catch((err) => {
            // set appropriate error for rejection in asyncFunction3
            throw new functions.https.HttpsError('not-found', 'Problem B');
        });
    });      
});

注意:我还添加了几个return语句,以确保 promise 被链接到链中并从导出的函数返回。 而且,我已经浓缩了逻辑以使其更易于阅读。


这也可能是 async/await 的情况(尽管我不完全确定functions.https.onCall()允许这样做):

exports.charge = functions.https.onCall(async (data) => {
    try {
        await asyncFunction1()
        await asyncFunction2();
    } catch(e) {
        throw new functions.https.HttpsError('not-found', 'Problem A');
    }
    try {
        await asyncFunction3();
    } catch(e) {
        throw new functions.https.HttpsError('not-found', 'Problem B');
    }
});

这样的东西会起作用吗?

exports.charge = functions.https.onCall(data => {
   return Promise.resolve().then(
      () => {
          return asyncFunction1();
      }).then(
      () => {
          return asyncFunction2();
      }).then(
      () => {
          return asyncFunction3();
      }).catch(
      err => {
          throw new functions.https.HttpsError(err);
      });
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM