更新
自撰写本文以来,lambda 已更新调用签名,现在通过 event, context, callback。
您应该使用callback(err, res),而不是调用context.done(err, res)。请注意,对于 context.done 的情况仍然适用于回调模式。
还应该补充一点,使用 API Gateways 代理和集成实现,整个线程几乎已经过时了。
如果您正在将 API Gateway 与 Lambda 集成,我建议您阅读这篇文章:http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
下面的原始回复
首先,让我们澄清一些事情。
context.done() 与 context.fail()/context.success
context.done(error, result); 只不过是context.fail(error); 和context.success(response); 的包装
Lambda 文档明确指出,如果错误为非 null,则忽略结果:
如果使用 RequestResponse(同步)调用类型调用 Lambda 函数,则该方法返回响应正文,如下所示:
如果错误为空,则将响应正文设置为结果的字符串表示形式。这类似于 context.succeed()。
如果错误不为空,则将响应正文设置为错误。
如果使用类型为 error 的单个参数调用该函数,则错误值将填充到响应正文中。
http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
这意味着无论您使用失败/成功或完成的组合,行为都是完全相同的。
API 网关和响应码映射
我已经测试了来自 Lambda 的响应处理与 API Gateway 中的响应代码映射相结合的每一种可能的组合。
这些测试的结论是 "Lambda Error RegExp" 仅针对 Lambda 错误执行,即:您必须调用 context.done(error); 或 context.fail(error); 才能真正触发 RegExp .
现在,这带来了一个问题,正如已经指出的那样,Lambda 将您的错误粘贴到一个对象中,并在您提供的任何内容上调用 toString():
{ errorMessage: yourError.toString() }
如果你提供了一个错误对象,你会得到这个:
{ errorMessage: "[object Object]" }
一点帮助都没有。
到目前为止我发现的唯一解决方法是调用
context.fail(JSON.stringify(error));
然后在我的客户端做:
var errorObject = JSON.parse(error.errorMessage);
它不是很优雅,但很有效。
作为我的错误的一部分,我有一个名为“代码”的属性。它可能看起来像这样:
{
code: "BadRequest",
message: "Invalid argument: parameter name"
}
当我对这个对象进行字符串化时,我得到:
"{\"code\":\"BadRequest\",\"message\":\"Invalid argument: parameter name\"}"
Lambda 会将此字符串粘贴到响应的 errorMessage 属性中,我现在可以在 API Gateway 响应映射中安全地 grep 查找 .*"BadRequest".*。
这是一个解决 Lambda 和 API 网关两个有点奇怪的怪癖的 hack:
- 为什么 Lambda 坚持包装错误而不是仅仅给出
它恢复原状?
- 为什么 API 网关不允许我们在
Lambda 结果,只有错误?
我正在就这两种相当奇怪的行为向亚马逊提出支持案例。