我正在尝试从AWS Lambda函数返回一个对象,而不是一个简单的字符串。
// ...
context.fail({
"email": "Email address is too short",
"firstname": "First name is too short"
});
// ...
我已经使用errorMessage
来映射对状态代码的错误响应,这很棒:
// ...
context.fail('That "username" has already been taken.');
// ...
我只是想尝试做一些AWS API Gateway无法承受的事情吗?
我还发现这篇文章有助于:Is there a way to change the http status codes returned by Amazon API Gateway?。
答案 0 :(得分:8)
<强>更新强>
自编写本文以来,lambda已更新了调用签名,现在通过了event, context, callback
。
您应该使用context.done(err, res)
而不是致电callback(err, res)
。请注意,context.done的情况仍然适用于回调模式。
还应该添加API网关代理和集成实现,这整个线程已经过时了。 如果您要将API网关与Lambda集成,我建议您阅读本文:http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
原始回复如下首先,让我们先澄清一些事情。
context.done(error, result);
只不过是context.fail(error);
和context.success(response);
的封套
Lambda文档明确指出,如果错误为非null,则忽略结果:
如果使用RequestResponse(同步)调用类型调用Lambda函数,则该方法返回响应正文,如下所示: 如果错误为null,则将响应主体设置为result的字符串表示形式。这类似于context.succeed()。 如果错误不为空,请将响应正文设置为错误。 如果使用类型为error的单个参数调用该函数,则将在响应正文中填充错误值。 http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
这意味着无论您是使用失败/成功还是完成,行为都完全相同无关紧要。
我已经测试了Lambda的每个可想到的响应处理组合以及API网关中的响应代码映射。
这些测试的结论是“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网关响应映射中grep .*"BadRequest".*
。
这是一个非常糟糕的工作,可以解决两个奇怪的Lambda和API网关怪癖:
我正准备与亚马逊就这两个相当奇怪的行为开启一个支持案例。
答案 1 :(得分:3)
您不必使用context.fail,使用success但发送不同的statusCode和errorMessage,这是我如何格式化输出的示例:
try {
// Call the callable function with the defined array parameters
// All the function called here will be catched if they throw exceptions
result.data = callable_function.apply(this, params);
result.statusCode = 200;
result.operation = operation;
result.errorMessage = ""
} catch (e) {
result.data = [];
result.statusCode = 500;
result.errorMessage = e.toString();
result.method = method;
result.resource = resource;
}
// If everything went smooth, send back the result
// If context succeed is not called AWS Lambda will fire the function
// again because it is not successfully exited
context.succeed(result);
使用消费者逻辑处理不同的错误案例逻辑,不要忘记你为函数运行的时间付出代价......
答案 2 :(得分:2)
您应该将context.fail
替换为context.done
,并仅将context.fail
用于非常严重的Lambda function
失败,因为它不允许多个输出参数。 Integration Response
能够通过对传递给context.done
的第一个参数执行regex来匹配映射模板,这也将HTTP状态代码映射到响应。您无法直接从Lambda
传递此响应状态代码,因为API Gateway
Integration Response
的角色是抽象HTTP协议。
请参阅以下内容:
context.done('Not Found:', <some object you can use in the model>);
和Integration Response
面板此设置:
您可以针对任何类型的错误复制类似的方法。您还应该创建错误模型并将其映射到您的回复。
答案 3 :(得分:-1)
对于那些试图解决这个问题并且无法完成这项工作的人(像我一样),请查看该帖子的devkit评论(保存我的一天):
https://forums.aws.amazon.com/thread.jspa?threadID=192918
完全在下面再现:
我自己也有这个问题,我相信换行 人物是罪魁祸首。
foo。*将匹配&#34; foo&#34;的出现次数。其次是任何字符 除了换行符。通常,这可以通过添加&#39; / s&#39;来解决。国旗,即 &#34; foo。* / s&#34;,但Lambda错误正则表达式似乎并不尊重这一点。
作为替代方案,您可以使用以下内容:foo(。| \ n)*