有什么方法可以在代码级别捕获AWS lambda超时错误?

San*_*Kim 4 amazon-web-services aws-lambda

有什么办法可以AWS lambda timed out在代码级捕获错误,以便在退出lambda函数之前有机会处理错误?

bac*_*112 11

更新:

改用内置Promise.race()函数:


module.exports.myFunction = async (event) => {

  // your real task
  const task = new Promise((resolve) => {
    setTimeout(() => resolve({ statusCode: 200, message: 'Task finished.' }), 1000);
  })

  // add a new "task": timeout 
  const timeout = new Promise((resolve) => {
    setTimeout(() => resolve({ statusCode: 504, message: 'Sorry, your task timed out!' }), 200);
  })
  
  // start them synchronously
  const res = await Promise.race([task, timeout]);
  return res;
};
Run Code Online (Sandbox Code Playgroud)

我想在这里分享我的解决方案:
假设我有一个 Lambda 处理函数,我设置的超时限制是 15 分钟。在此函数中,我有一个名为的异步函数work(),它可能需要 15 分钟以上的时间。

为了从 Lambda 捕获超时错误,我的方法是:
我创建一个名为 的新异步函数timeout(),该函数在 14.9 分钟后返回。我让work()timeout()函数同时启动,如果work()可以在 14.9 分钟内完成,则work()提前返回timeout(),否则,timeout()提前返回。
您可以通过此图表更轻松地看到它:

在此处输入图片说明

这正是race()操作符从rxjs.

这是通过使用实现这个想法的代码rxjs

module.exports.myFunction = async (event) => {
  function task() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('finished!');
      }, 15 * 60 * 1000);
    });
  }

  function timeout() {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('timeout!');
      }, 14.9 * 60 * 1000);
    });
  }


  const res = await new Promise((resolve, reject) => {
    race(from(task()), from(timeout()))
      .subscribe(msg => {
        resolve(msg);
      })
  });

  return { res };
};
Run Code Online (Sandbox Code Playgroud)


tho*_*ace 10

尽管lambda环境不会触发“定时退出”事件,但是您可以自己进行一些琐碎的操作。

每种语言都有context对象公开的功能,以获取剩余时间(以毫秒为单位)

您可以将其与任何所用语言的计时器功能配合使用,以确保在超时之前得到通知。

例如(节点):

function handler(event, context, callback) {
  const timer = setTimeout(() => {
    console.log("oh no i'm going to timeout in 3 seconds!");
    // &c.
  }, context.getRemainingTimeInMillis() - 3 * 1000);
  // rest of code...
  clearTimeout(timer);
  callback(null, result);
}
Run Code Online (Sandbox Code Playgroud)

  • 确保?我不明白这如何可靠地“捕捉”超时,如果您使用阻塞的第三方库需要 5 秒来完成某项任务怎么办? (2认同)
  • 是的,我认为您对 node 的看法是正确的,不幸的是,在我的情况下,一切都是在 python 中完成的,我想每 15 分钟检查一次任务是否有其他尚未关闭其流程的任务,然后重试或分解为较小的任务是一个解决方案 (2认同)
  • 对于 Python 用户,以下是 `context` 对象的示例 https://docs.aws.amazon.com/lambda/latest/dg/python-context.html 感谢 @thomasmichaelwallace 为我指明了正确的方向。 (2认同)
  • 确保将 `// rest of code...` 包装在 try-finally 中,并将 `clearTimeout` 放在 `finally` 块中。如果没有这个,如果你的 lambda 有一个未处理的异常,超时不会被清除,并且未来的 lambda 调用可能最终会处理先前(失败的)lambda 调用的超时回调(因为如果有需要,lambda 会重用 nodejs 运行时) )。 (2认同)