我遵循指南here来设置预注册触发器。
但是,当我使用callback(null, event)
时,我的lambda函数将永远不会真正返回,并且最终会收到错误消息
{代码:“ UnexpectedLambdaException”, 名称:“ UnexpectedLambdaException”, 消息:“ arn:aws:lambda:us-east-2:642684845958:function:proj-dev-confirm-1OP5DB3KK5WTA失败,并在调用Lambda函数时出现错误套接字超时。” }
我发现了一个类似的link here,说要使用context.done()
。
切换后,效果很好。
有什么区别?
exports.confirm = (event, context, callback) => {
event.response.autoConfirmUser = true;
context.done(null, event);
//callback(null, event); does not work
}
答案 0 :(得分:2)
回到原始的Lambda运行时环境(适用于Node.js 0.10),Lambda在context
对象context.done(err, res)
context.succeed(res)
和context.fail(err)
中提供了辅助功能。
此文件先前已记录,但已被删除。
Using the Earlier Node.js Runtime v0.10.42是Lambda文档中不再存在的页面的存档副本,解释了如何使用这些方法。
启动Lambda的Node.js 4.3运行时时,它们仍然是向后兼容的(并且仍然可用,但未记录),并引入了callback(err, res)
。
这是您问题的性质,以及为什么您发现的两个解决方案实际上可以解决问题。
然而,Context.succeed,context.done和context.fail不仅仅是簿记–它们会导致请求在当前任务完成后返回并立即冻结该过程,即使其他任务仍保留在Node.js中事件循环。通常,如果这些任务代表不完整的回调,那不是您想要的。
https://aws.amazon.com/blogs/compute/node-js-4-3-2-runtime-now-available-on-lambda/
因此,在callback
中,Lambda函数现在以更范式上正确的方式运行,但是如果您打算在调用之间发生冻结期间将某些对象保留在事件循环中,则会出现问题-与旧的(不推荐使用的)done
fail
succeed
方法中,使用回调不会立即挂起。而是等待事件循环为空。
context.callbackWaitsForEmptyEventLoop
(默认为true
),以便您希望在调用回调后立即让Lambda函数返回的情况将其设置为false
,不管事件循环中发生了什么。默认值为true
,因为如果您不考虑容器重用的含义,false
可能会掩盖函数中的错误并可能导致非常不稳定/意外的行为-因此,不应将其设置为{{ 1}},除非直到您了解为什么需要它。
需要false
的常见原因是您的函数建立了数据库连接。如果在全局变量中创建数据库连接对象,则该对象将在事件循环中具有打开的套接字以及可能的其他内容,例如计时器。这样可以防止回调导致Lambda返回响应,直到这些操作也完成或调用超时计时器触发。
确定为什么需要将其设置为false
,如果有正当的理由,那么使用它是正确的。
否则,您的代码可能存在需要理解和修复的错误,例如,在调用回调时,使请求进行中或其他工作未完成。
那么,我们如何解析Cognito错误?起初,这似乎很不寻常,但是现在很明显不是。
在执行功能时,Lambda将抛出错误,表明任务在配置的秒数后超时。您应该会发现这是在Lambda控制台中测试功能时发生的事情。
不幸的是,当调用Lambda函数时,Cognito似乎采取了内部设计捷径,而不是等待Lambda使调用超时(这可能会占用Cognito内的资源)或在Cognito的最大持续时间上强加自己的显式计时器将等待Lambda响应,它依赖于较低层的套接字计时器来约束此等待...因此在调用超时时会引发“意外”错误。
进一步复杂的解释错误消息,错误中缺少引号,并在其中插入了下层异常。
对我来说,如果错误显示如下,问题将更加清楚:
false
此格式将更清楚地表明,当 Cognito 调用该函数时,它引发了内部'arn:aws:lambda:...' failed with error 'Socket timeout' while invoking Lambda function
错误(与 Lambda 遇到意外的内部错误相反)错误,这是我最初的假设,也是错误的假设)。
对于Cognito来说,对Lambda函数施加某种响应时间限制是非常合理的,但是我看不到有文档记录。我怀疑Lambda函数本身的超时时间短(使它更迅速地失败)会导致Cognito抛出一些更有用的错误,但是在我看来,Cognito应该被设计为包含使此错误成为预期的,已定义的错误的逻辑,而不是将其归类为“意外”。
答案 1 :(得分:0)
作为更新,运行时Node.js 10.x处理程序支持async function,该onSubgridBeforeExpand利用return
和throw
语句分别返回成功或错误响应。此外,如果函数执行异步任务,则可以返回Promise
,然后分别使用resolve
或reject
返回成功或错误。两种方法都可以通过不需要context
或callback
来将完成信号通知给调用方来简化事情,因此您的lambda函数可能看起来像这样:
exports.handler = async (event) => {
// perform tasking...
const data = doStuffWith(event)
// later encounter an error situation
throw new Error('tell invoker you encountered an error')
// finished tasking with no errors
return { data }
}
当然,您仍然可以使用context
,但这不是表示完成的必需条件。