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

Http 如何从AWS Lambda函数返回错误集合/对象并映射到AWS API网关响应代码,http,amazon-web-services,aws-lambda,http-response-codes,aws-api-gateway,Http,Amazon Web Services,Aws Lambda,Http Response Codes,Aws Api Gateway,我试图从AWS Lambda函数返回一个对象,而不是一个简单的字符串 // ... context.fail({ "email": "Email address is too short", "firstname": "First name is too short" }); // ... 我已经使用了errorMessage将错误响应映射到状态代码,这非常好: // ... context.fail('That "username" h

我试图从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.');
// ...
我只是想做一些AWSAPI网关负担不起的事情吗


我还发现这篇文章很有帮助:.

您应该将
上下文.fail
替换为
上下文.done
并仅在非常严重的
Lambda函数
失败时使用
上下文.fail,因为它不允许多个输出参数<代码>集成响应
能够通过对传递到
上下文的第一个参数执行正则表达式来匹配映射模板。完成
这也将HTTP状态代码映射到响应。您不能直接从
Lambda
传递此响应状态代码,因为它是
API网关
Integration response
抽象HTTP协议的角色

见下文:

context.done('notfound:',)

而集成响应面板将显示此设置:


对于任何类型的错误,您都可以复制类似的方法。您还应该创建错误模型并将其映射到您的响应。

您不必使用context.fail,也可以使用success,但可以发送不同的状态码和错误消息,下面是我如何格式化输出的示例:

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);
使用使用者逻辑来处理不同的错误案例逻辑,不要忘记您为功能运行的时间付费…

更新 自撰写本文以来,lambda已经更新了调用签名,现在传递了
事件、上下文和回调

不要调用
context.done(err,res)
您应该使用
callback(err,res)
。请注意,context.done的情况仍然适用于回调模式

还应该补充一点,使用API网关代理和集成实现,整个线程几乎已经过时。 如果要将API网关与Lambda集成,我建议您阅读本文:

原始答复如下 首先,让我们把一些事情弄清楚

context.done()与context.fail()/context.success
context.done(错误、结果)
不过是
context.fail(错误)的包装器
上下文。成功(响应)
Lambda文档明确指出,如果错误为非空,则忽略结果:

如果Lambda函数是使用RequestResponse(同步)调用类型调用的,则该方法返回响应体,如下所示: 如果错误为null,则将响应主体设置为结果的字符串表示形式。这与context.success()类似。 如果错误不为null,则将响应正文设置为error。 如果使用类型为error的单个参数调用函数,则会在响应正文中填充错误值。

这意味着,不管你是使用失败/成功还是完成的组合,行为都是完全相同的

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

这些测试的结论是,“Lambda Error RegExp”仅针对Lambda错误执行,即:您必须调用
context.done(Error)
上下文。失败(错误)用于实际触发RegExp

现在,这就出现了一个问题,正如已经注意到的,Lambda接受您的错误并将其粘贴到一个对象中,并对您提供的任何对象调用
toString()

{ errorMessage: yourError.toString() }
如果您提供了一个错误对象,您将得到以下结果:

{ errorMessage: "[object Object]" }
一点帮助都没有

到目前为止,我找到的唯一解决办法是打电话

context.fail(JSON.stringify(error));
然后在我的客户中:

var errorObject = JSON.parse(error.errorMessage);
它不是很优雅,但很管用。 作为错误的一部分,我有一个名为“code”的属性。它可能看起来像这样:

{ 
    code: "BadRequest", 
    message: "Invalid argument: parameter name" 
}
当我字符串化此对象时,我得到:

"{\"code\":\"BadRequest\",\"message\":\"Invalid argument: parameter name\"}"
Lambda将把这个字符串粘贴到响应的errorMessage属性中,我现在可以在API网关响应映射中安全地grep
*“BadRequest”。*

这在很大程度上是一种针对Lambda和API网关两个有点奇怪的怪癖的黑客行为:

  • 为什么Lambda坚持要包装错误而不是仅仅给出错误 它恢复原样了吗
  • 为什么API网关不允许我们在 Lambda结果,只有错误吗

  • 我正准备就这两种奇怪的行为与亚马逊展开一个支持案例。

    对于那些尝试了所有方法解决这个问题但无法解决这个问题的人(像我一样),请查看这篇帖子上的thedevkit评论(拯救了我的一天):

    完全复制如下:

    我自己也有过一些问题,我相信新线 人物是罪魁祸首

    foo.*将匹配后跟任何字符的“foo” 除了新线。通常通过添加“/s”标志来解决此问题,即。 “foo.*/s”,但Lambda错误regex似乎不尊重这一点

    作为替代方案,您可以使用以下内容:foo(.|\n)*


    在没有Lambda Regex错误模式的情况下,当我在200和404上进行测试时,404的响应代码永远不会返回。我通过设置为404的“statusCode”获得了正确的数据,但实际的响应代码是200。我遗漏了什么吗?是的,在集成响应中,不要再次映射您的响应,只需发送lambda输出,并使用默认的响应映射。我刚刚删除了“方法响应”和“集成响应”中的所有响应代码,当我测试时,将
    statusCode
    设置为200或400,我只得到500。当我在“方法响应”中添加200和400时,没有变化。当我加上200和40