【问题标题】:UnhandledPromiseRejectionWarning : error handling in an async callback functionUnhandledPromiseRejectionWarning :异步回调函数中的错误处理
【发布时间】:2020-11-22 10:14:45
【问题描述】:

我有一个异步回调函数,如果不满足某些条件会抛出错误。

但我收到以下错误

(节点:77284)UnhandledPromiseRejectionWarning:错误:未找到

UnhandledPromiseRejectionWarning:未处理的承诺拒绝。此错误源于在没有 catch 块的情况下抛出异步函数内部,或拒绝未使用 .catch() 处理的承诺。

我的代码:

async deleteItem(id: string): Promise<void> {
    const ref = firestoreDB.collection("items").doc(id);

    firestoreDB
      .runTransaction(async (transaction: FirebaseFirestore.Transaction) => {
        let doc = await transaction.get(ref);
        if (doc.exists) {
          transaction.delete(ref);
        } else {
          throw new NotFoundException();
        }
      })
      .catch((err) => {
        if (err instanceof NotFoundException) {
          throw err;
        } else {
          throw new HttpException(
            "Something went wrong",
            HttpStatus.INTERNAL_SERVER_ERROR
          );
        }
      });
  }

从回调函数中抛出错误的正确方法是什么?

【问题讨论】:

  • 尝试将异步回调函数实现包装在 try...catch 中
  • 也许你在transaction.delete(ref);之前忘记了await

标签: javascript node.js es6-promise


【解决方案1】:

在查看.runTransaction() 的代码示例时,它看起来像是返回了一个 Promise,并且会从它的回调中传播一个 Promise 拒绝(这对于普通回调来说有点不同的接口),但无论如何,它看起来就像你只需要从 deleteItem() 方法中返回来自 firestoreDB.runTransaction() 的承诺,然后确保该方法的调用者使用 .catch() 来处理任何错误。

async deleteItem(id: string): Promise<void> {
    const ref = firestoreDB.collection("items").doc(id);

    // add return here
    return firestoreDB
      .runTransaction(async (transaction: FirebaseFirestore.Transaction) => {
        let doc = await transaction.get(ref);
        if (doc.exists) {
          transaction.delete(ref);
        } else {
          throw new NotFoundException();
        }
      })
      .catch((err) => {
        if (err instanceof NotFoundException) {
          throw err;
        } else {
          throw new HttpException(
            "Something went wrong",
            HttpStatus.INTERNAL_SERVER_ERROR
          );
        }
      });
  }

那么,无论你打电话给.deleteItem()

obj.deleteItem(...).catch(err => {
    // handle error here
});

【讨论】:

  • 谢谢,成功了。该函数的调用者是一个 Nest.js 休息控制器,它返回服务方法,因此它将处理 http 错误的传播。返回交易承诺解决了问题。
猜你喜欢
  • 2016-12-13
  • 1970-01-01
  • 2014-05-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 2017-06-13
  • 2021-03-08
相关资源
最近更新 更多