【问题标题】:How to handle errors in Firestore transactions inside https cloud function?如何处理 https 云功能内的 Firestore 事务中的错误?
【发布时间】:2026-01-21 01:05:02
【问题描述】:

如果某些先决条件失败(在事务的读取部分),我想向客户端抛出一个 https 错误。另外,如果事务由于意外错误而失败,我想抛出“不可用”错误。

await firestore
  .runTransaction(async (transaction) =>
    transaction.get(userRef).then((doc) => {
        const { totalPoints } = doc.data();

        if (totalPoints > 1000) {
          ...
        } else {
          throw new functions.https.HttpsError(
            "failed-precondition",
            "You have less than 1000 points."
          );
        }
    })
  )
  .catch((err) => {
    throw new functions.https.HttpsError(
      "unavailable",
      "Please, try again later."
    );
  });

问题是,如果我在 then 中抛出 https 错误,catch 会得到它并抛出另一个 https 错误。

抛出“failed-precondition”错误时如何避免进入catch?

【问题讨论】:

    标签: javascript google-cloud-firestore async-await google-cloud-functions try-catch


    【解决方案1】:

    我已经用 Promise.reject() 解决了这个问题

    我知道这不是最好的方法,但很有效。寻找更好的方法。

    await firestore
      .runTransaction(async (transaction) =>
        transaction.get(userRef).then((doc) => {
            const { totalPoints } = doc.data();
    
            if (totalPoints > 1000) {
              ...
            } else {
              return Promise.reject({
                type: "failed-precondition",
                message: "You have less than 1000 points."
              });
            }
        })
      )
      .catch((err) => {
         if (err.type === "failed-precondition") {
            throw new functions.https.HttpsError(err.type, err.message);
         }
         else {
           throw new functions.https.HttpsError(
              "unavailable",
              "Please, try again later."
           );
         }
      });
    

    【讨论】:

      【解决方案2】:

      对于我所有的 Cloud Functions,我有一个*的 try-catch,它可以捕获未知错误并让 HttpsError 错误继续沿链继续下去。

      if (e instanceof https.HttpsError) throw e;
      console.error("Encountered with an undefined error. Error: ", e);
      throw new https.HttpsError(
        "unknown",
        "There was an unknown error."
      );
      

      你可以做类似的事情(当然用functions.https.HttpsError替换https.HttpsError)。

      这使我可以按原样传递我在代码中预定义的错误,并在记录 Cloud Logging 错误时向我的用户提供错误消息。

      【讨论】: