How to handle errors in Firestore transactions inside https cloud function?

I want to throw an https error to the client if some pre-condition fails (in the read part of the transaction). Also, I want to throw an "unavailable" error if the transaction fails because of an unexpected error.

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."
    );
  });

The problem is that, if I throw the https error inside the then, the catch will get it and throw an other https error.

How can I avoid entering the catch when throwing the "failed-precondition" error?

5 thoughts on “How to handle errors in Firestore transactions inside https cloud function?”

  1. I have solved the problem with Promise.reject()

    I know that this is not the best way, but works. Looking for a better approach.

    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."
           );
         }
      });
    
    Reply

Leave a Comment