Google 云函数 - 重试

Google Cloud Functions - Retry

我有这个幂等函数,它包含我为 Google Cloud Functions 编写的多个承诺。 我想启用重试,因为我使用的 API 非常不一致。这需要在需要重试时 returned 拒绝承诺。

因此我尝试 return 一个 promise.all([]) 但当其中一个承诺失败时,terminate/stop 没有这个功能。然后它甚至会进入 promise.all().then()?只有当所有 4 个承诺都成功时才会发生这种情况。

谁能给我指出正确的方向?我的尝试是否有意义?

exports.scheduleTask = functions
  .firestore.document("tasks_schedule/{servicebonnummer}")
  .onCreate((snap, context) => {

    servicebonnummer = snap.data().data.servicebonnummer;
    bondatum = snap.data().data.bondatum;
    servicestatus = snap.data().data.servicestatus;
    tijdstip = snap.data().data.tijdstip;
    firestorePromise = null;
    firestoreFinish = null;
    cashPromise = null;
    cashFinish = null;

    //Firebase
    //firestoreSchedule executes the required promise
    //checkFinished points to a database where it checks a boolean for idempotency
    //firestoreFinish writes to this database and sets the boolean to true when the promise is successful

    if (!checkFinished("tasks_schedule", servicebonnummer, "firestore")) {
      firestorePromise = scheduleFirestore(
        servicebonnummer,
        bondatum,
        servicestatus,
        tijdstip
      )
        .then(output => {
          firestoreFinish = markFinished(
            "tasks_schedule",
            servicebonnummer,
            "firestore"
          );
          return output;
        })
        .catch(error => {
          console.error(
            "scheduleFirestore - Error connecting to Firestore: ",
            error
          );
          return error;
        });
    }

    //SOAP API
    //cashSchedule executes the required promise
    //checkFinished points to a database where it checks a boolean for idempotency
    //cashFinish writes to this database and sets the boolean to true when the promise is successful

    if (!checkFinished("tasks_schedule", servicebonnummer, "cash")) {
      cashPromise = scheduleCash(
        servicebonnummer,
        moment(bondatum),
        servicestatus,
        tijdstip
      )
        .then(result => {
          if (result[0].response.code === "2") {
            cashFinish = markFinished(
              "tasks_schedule",
              servicebonnummer,
              "cash"
            );
            return result;
          }
          throw new Error("Validation error, response not successful");
        })
        .catch(error => {
          console.error("scheduleCash - Error connecting to CASH API: ", error);
          return error;
        });
    }

    //CHECK PROMISES

    return Promise.all([
      firestorePromise,
      firestoreFinish,
      cashPromise,
      cashFinish
    ])
      .then(result => {
        removeTask("tasks_schedule", servicebonnummer);
        return result;
      })
      .catch(error => {
        console.error("scheduleTask - Retry: ", error);
        return error;
      });
  });

如果你编码:

let somePromise = new Promise(...);
return somePromise.then(funcA).catch(funcB);

那你确实是在return承诺。但是,由于您的代码中有该承诺的处理程序,我们需要更详细地查看发生的情况。让我们假设 somePromise 被拒绝。这意味着将调用 catch() 处理程序。 that 捕获处理程序的结果将是 returned 承诺的最终解决方案。

如果我们查看 Promise.catch() 的 MDN 文档,我们会发现以下内容:

The Promise returned by catch() is rejected if onRejected throws an error or returns a Promise which is itself rejected; otherwise, it is resolved.

如果我们查看您的代码,

catch(error => {
  console.error("scheduleTask - Retry: ", error);
  return error;
});

现在问:

  1. 此代码是否会引发错误?不……它没有 throw 语句,因此只有 returns 传入的值。
  2. 代码 return 是 Promise 吗?不……它传递了一个错误值,只是 return 那个错误值,我很确定它本身不会是一个 Promise。

这意味着整个 Promise returned 以 resolved 状态而非 rejected 状态结束,因此整个 Cloud Function 被认为已经结束并且不会重试。

您的选择可能是:

catch(error => {
  console.error("scheduleTask - Retry: ", error);
  throw error;
});

catch(error => {
  console.error("scheduleTask - Retry: ", error);
  return Promise.reject(error);
});

参考文献: