如何从AWS Lambda函数返回错误集合/对象并映射到AWS API Gateway响应代码

kal*_*hua 2 http amazon-web-services http-response-codes aws-lambda aws-api-gateway

我试图从AWS Lambda函数返回一个对象而不是一个简单的字符串.

// ...
    context.fail({
        "email": "Email address is too short",
        "firstname": "First name is too short"
    });
// ...
Run Code Online (Sandbox Code Playgroud)

我已经使用了errorMessage映射错误响应状态代码,这很好:

// ...
    context.fail('That "username" has already been taken.');
// ...
Run Code Online (Sandbox Code Playgroud)

我只是想尝试做一些AWS API Gateway无法承受的事情吗?

我也已经发现这篇文章有所帮助:有没有办法更改Amazon API Gateway返回的http状态代码?.

pol*_*ene 9

更新 自编写之时,lambda已更新调用签名,现在已通过event, context, callback.

而不是打电话给context.done(err, res)你应该使用callback(err, res).请注意,context.done的真实情况仍然适用于回调模式.

还应该添加API网关代理和集成实现,这整个线程已经过时了.如果您要将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函数,则该方法返回响应正文,如下所示:如果错误为null,则将响应正文设置为结果的字符串表示形式.这与context.succeed()类似. 如果错误不为null,请将响应正文设置为error. 如果使用类型为error的单个参数调用该函数,则将在响应正文中填充错误值. http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html

这意味着无论你是使用失败/成功还是成功的组合都无关紧要,行为完全相同.

API网关和响应代码映射

我已经测试了Lambda的响应处理的每个可想到的组合以及API网关中的响应代码映射.

这些测试的结论是"Lambda Error RegExp"仅针对Lambda错误执行,即:您必须调用context.done(error);context.fail(error);RegExp实际触发.

现在,这就出现了一个问题,因为已经注意到,Lambda会将您的错误记录在一个对象中并调用toString()您提供的任何内容:

{ errorMessage: yourError.toString() }
Run Code Online (Sandbox Code Playgroud)

如果你提供了一个错误对象,你会得到这个:

{ errorMessage: "[object Object]" }
Run Code Online (Sandbox Code Playgroud)

根本没有帮助.

到目前为止,我发现的唯一解决方法是致电

context.fail(JSON.stringify(error));
Run Code Online (Sandbox Code Playgroud)

然后在我的客户端做:

var errorObject = JSON.parse(error.errorMessage);
Run Code Online (Sandbox Code Playgroud)

它不是很优雅,但它的工作原理.作为我的错误的一部分,我有一个名为"代码"的属性.它可能看起来像这样:

{ 
    code: "BadRequest", 
    message: "Invalid argument: parameter name" 
}
Run Code Online (Sandbox Code Playgroud)

当我对此对象进行字符串化时,我得到:

"{\"code\":\"BadRequest\",\"message\":\"Invalid argument: parameter name\"}"
Run Code Online (Sandbox Code Playgroud)

Lambda会将此字符串粘贴在响应的errorMessage属性中,现在我可以安全地.*"BadRequest".*在API网关响应映射中进行grep .

这是一个非常黑的,可以解决Lambda和API Gateway的两个奇怪的怪癖:

  1. 为什么Lambda坚持包装错误而不是仅仅按原样回复?
  2. 为什么API Gateway不允许我们在Lambda结果中grep,只有错误?

我正准备与亚马逊就这两个相当奇怪的行为开启一个支持案例.