如何从错误消息中注入 header

How to inject a header from the errormessage

我一直在尝试为错误响应状态注入自定义 header(但失败了)。

我使用了一个非常简单的 lambda

exports.handler = (event, context, callback) => {
   // TODO implement

   //callback(null, 'Hello from Lambda');

   var error = {
       name:"error", 
       message:"I am a failure",
       statusCode: 400
   };

   error["x-test"] = 'foo';

   callback(JSON.stringify(error), null);
};

在 api 网关中,我完成了以下操作:

设置 CORS 以包含 x-test 响应模板 = "$input.path('$.errorMessage')" 响应参数包括:

method.response.header.x-test = integration.response.body.x-test

此外,我使用 '.*statusCode.*?400.*'

映射了一个 statusCode

结果是空的。

所以我决定退后一步,看看如果我这样做会发生什么:

method.response.header.x-test = integration.response.body

我发现我得到了 errorMessage 的字符串化响应。

{"x-test":"{\"errorMessage\":\"{\\"name\\":\\"error\\",\\"message\\":\\"I am a failure\\",\\"statusCode\\":400,\\"x-test\\":\\"foo\\"}\"}"}

所以我决定通过执行以下操作来更改响应模板以将其强制为 json:

响应模板 = "$util.parseJson($input.path('$.errorMessage'))"

我仍然得到字符串化的响应:

{"x-test":"{\"errorMessage\":\"{\\"name\\":\\"error\\",\\"message\\":\\"I am a failure\\",\\"statusCode\\":400,\\"x-test\\":\\"foo\\"}\"}"}

我的猜测是它没有按预期进行转换,而只是针对最终输出。

那么你如何获取一个值并将其推入 header?

谢谢, 凯莉

我认为这更多是关于 Lambda 和 APIGateway 强加的限制的设计选择。我会尽量把我的想法走一遍。

首先,在 Lambda 中,callback(error, result) 函数可以将错误 [​​=40=]string 作为第一个参数,或者object 作为结果响应。如果你想传递一个简单的错误信息,你绝对可以这样做。但是,在您的情况下,当您尝试传递整个错误 object 时,选择第二个选项显然是更好的解决方案(与将 object 字符串化并将其解析为 object 相比再次)。因此,您的 Lambda 函数的最后一行应该是:

callback(null, error);

是的,在这种情况下,如果您在 Lambda 中测试您的函数,输出结果将不再是红色并将其标记为错误,但这无关紧要,因为您可以格式化您的 header s 和 API 网关中的响应。

现在您需要在API网关中进行设置,其中您需要使用Lambda 传递的object。

使用方法执行接口配置headers.

其实很简单
  • Method Response 中,您需要添加要包含在特定状态代码响应中的 headers,其中你的情况是x-test。 (如果你想要 API 到 return 不同的状态代码,你也可以在这个面板中配置。)

  • 然后进入Integration Response,同样的状态码下,会看到添加的header可用。根据 AWS 的 this 文档,您可以使用 integration.response.body.JSONPath_EXPRESSION 分配 header 值(这是您应该 return object 而不是字符串的另一个原因Lambda,因为在这个阶段没有正式的 API 来从字符串中解析 object)。这次,由于您的 Lambda 正在传递 object,x-test header 的值是:

integration.response.body['x-test']

  • 现在您的 API 应该包含正确的 header。

注意: 为了在API网关中设置不同的状态码,你应该留下一些可区分的数据字段(你的状态码:400应该完美工作)在你的回应 body,所以你可以使用 RegEx 将这些字段匹配到特定的状态代码。

所以...以上不适用于成功消息。我在谈论错误处理设计模式时发现了这个 blog。显然,他们建议的只是在出现错误时映射状态代码,在这种情况下,不应传递 body(仅传递 errorMessage),因为浏览器不会关心状态代码的响应 body无论如何都不是 200。

我想毕竟,Lambda 将 object 传递给 API 网关,同时自定义状态代码和 header 是不可能的?

这是因为您正在对来自您的 Lambda 函数的错误 object 进行字符串化。 API 网关尝试解析 JSON-Path 表达式,但无法计算字符串中的 "x-test"。如果你 return 一个 object 而不是字符串,这应该可以工作。

您可能需要考虑使用 proxy integrations,它允许您直接从 Lambda 函数控制 headers 和状态。

更新:我写了一篇关于这个主题的博客 post,其中包含示例代码 @ https://rpgreen.wordpress.com/2017/01/25/how-to-send-response-headers-for-aws-lambda-function-exceptions-in-api-gateway/