【问题标题】:Google Cloud Functions - Retry谷歌云函数 - 重试
【发布时间】:2020-04-23 08:26:15
【问题描述】:

我有这个具有多个 Promise 的幂等函数,是我为 Google Cloud Functions 编写的。 我想启用重试,因为我使用的 API 非常不一致。这需要在需要重试时返回被拒绝的承诺。

因此,我尝试返回一个 promise.all([]) ,但是当其中一个承诺失败时,它不会终止/停止函数。然后它甚至进入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;
      });
  });

【问题讨论】:

  • From MDN: "Promise.all() 返回一个 Promise,当所有作为 iterable 传递的 Promise 都已实现或当 iterable 不包含 Promise 时,它​​会根据原因拒绝。第一个被拒绝的承诺。”因此,如果有任何承诺失败,它应该拒绝(致电catch())。这不是发生在你身上吗?
  • 这里缺少的关键是 catch 返回一个成功解决的承诺,如果你没有通过创建一个返回新的错误来传播另一个错误。

标签: javascript node.js promise google-cloud-functions idempotent


【解决方案1】:

如果你编码:

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

那么你确实是在回报一个承诺。但是,由于您的代码中有该 Promise 的处理程序,因此我们需要更详细地了解发生了什么。让我们假设somePromise 被拒绝。这意味着将调用catch() 处理程序。 那个 catch 处理程序的结果将是返回的 Promise 的最终解决方案。

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

如果 onRejected 抛出一个异常,catch() 返回的 Promise 将被拒绝 错误或返回一个本身被拒绝的 Promise;否则,它是 解决了。​​

如果我们查看您的代码,

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

现在问:

  1. 此代码是否会引发错误?不...它没有 throw 语句,因此只返回传入的值。
  2. 代码是否返回 Promise?不...它传递了一个错误值并简单地返回该错误值,我很确定它本身不会是一个 Promise。

这意味着返回的整体 Promise 以 resolved 状态结束,而不是 rejected 状态,因此整体 Cloud Function 被认为已经结束并且不会重试.

您的选择可能是:

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

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

参考资料:

【讨论】:

    猜你喜欢
    • 2019-02-15
    • 2018-12-07
    • 2018-10-02
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 2018-04-19
    相关资源
    最近更新 更多