AWS Lambda,API Gateway 返回 Malformed Lambda 代理响应,502 错误

Posted

技术标签:

【中文标题】AWS Lambda,API Gateway 返回 Malformed Lambda 代理响应,502 错误【英文标题】:AWS Lambda, API Gateway returns Malformed Lambda proxy response, 502 error 【发布时间】:2017-10-04 05:26:36 【问题描述】:

经过大量谷歌搜索和几个小时的反复试验,我无法找出为什么会收到此错误消息:

由于配置错误导致执行失败:格式错误的 Lambda 代理响应

当我使用测试 lambda 功能运行 lambda 时,它运行良好。 对类似问题的回答表明来自 lambda 的响应需要满足这种格式:


  "isBase64Encoded": true|false,
  "statusCode": httpStatusCode,
  "headers":  "headerName": "headerValue", ... ,
  "body": "..."

以下是我正在使用的 lambda(遵循这种格式):

'use strict';

var aws = require('aws-sdk');
var ses = new aws.SES();

var RECEIVER = "XXXX@XXXX.com";
var SENDER = "XXXX@XXXX.com";

const response_success = 
      'isBase64Encoded': false,
      'statusCode': 200,
      'headers': 
          'Content-Type': 'application/json',
      ,
      body: JSON.stringify(
        message: 'ok'
      ),
;

const response_error = 
    'isBase64Encoded': false,
    'statusCode': 400,
    'headers': 
        'Content-Type': 'application/json',
    ,
    body: JSON.stringify(
        message: 'error'
    ),
;

exports.handler = (event, context, callback) => 
    sendEmail(event, function(error, data) 
        if (error) 
           callback(response_error);
         else 
           callback(null, response_success);
        
    );
;

function sendEmail(event, done) 
    var params = 
        Destination: 
            ToAddresses: [
                RECEIVER
            ]
        ,
        Message: 
            Body: 
                Text: 
                    Data: event.message,
                    Charset: 'UTF-8'
                
            ,
            Subject: 
                Data: 'Lamda Test Email',
                Charset: 'UTF-8'
            
        ,
        Source: SENDER
    
    ses.sendEmail(params, done);

我认为这不是配置问题,如果有任何帮助,我正在使用 Terraform 构建基础架构。 提前致谢!

编辑:(添加了下面的错误日志)

Execution log for request test-request
Fri May 05 16:36:22 UTC 2017 : Starting execution for request: test-invoke-request
Fri May 05 16:36:22 UTC 2017 : HTTP Method: POST, Resource Path: /messages
Fri May 05 16:36:22 UTC 2017 : Method request path: 
Fri May 05 16:36:22 UTC 2017 : Method request query string: 
Fri May 05 16:36:22 UTC 2017 : Method request headers: 
Fri May 05 16:36:22 UTC 2017 : Method request body before transformations:  "message" : "test" 
Fri May 05 16:36:22 UTC 2017 : Endpoint request URI: https://lambda.eu-west-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:eu-west-1:670603659598:function:mailer_lambda/invocations
Fri May 05 16:36:22 UTC 2017 : Endpoint request headers: x-amzn-lambda-integration-tag=test-request, Authorization=****************************************************************************************************************************************************************************************************************************************************************************************************************************************cd4bef, X-Amz-Date=20170505T163622Z, x-amzn-apigateway-api-id=jnnd4wh3f8, X-Amz-Source-Arn=arn:aws:execute-api:eu-west-1:670603659598:jnnd4wh3f8/null/POST/messages, Accept=application/json, User-Agent=AmazonAPIGateway_jnnd4wh3f8, X-Amz-Security-Token=FQoDYXdzEPH//////////wEaDB1y8s+RanRAP61EAyK3A1f/o2BrYfqUOQwsrn7bRF6OMmeD3Se+WVWA1reC3tZZ6+IfnFa0LVNnaaNM27o/Vqc/m4tnQR5xUACK3I6ssbkwHj9E4sM3sQ4L+zNQSnkZhMAIRxbyxHJRp1E9/8XnVxRJAWF5ynWCmDxe2tQQ8SXCnQKIKzJypIgp0E0BD3hZ92soW6wID64uaufk+qYXiV7AJxd+Z9Gg1TyiwacUA2i0g4xsjDqeAA5wFbI9KoiYK6/+uwpQ5mxdxg6JIxS7H9jULRRn7V9E4YVXsXCWXh8RXqGmigGzWXChYAD3S7b9rBLUpTga3t3SlnnK [TRUNCATED]
Fri May 05 16:36:22 UTC 2017 : Endpoint request body after transformations: "resource":"/messages","path":"/messages","httpMethod":"POST","headers":null,"queryStringParameters":null,"pathParameters":null,"stageVariables":null,"requestContext":"accountId":"670603659598","resourceId":"90rzx3","stage":"test-invoke-stage","requestId":"test-invoke-request","identity":"cognitoIdentityPoolId":null,"accountId":"670603659598","cognitoIdentityId":null,"caller":"670603659598","apiKey":"test-invoke-api-key","sourceIp":"test-invoke-source-ip","accessKey":"ASIAJA3SYDRPGE36PMXQ","cognitoAuthenticationType":null,"cognitoAuthenticationProvider":null,"userArn":"arn:aws:iam::670603659598:root","userAgent":"Apache-HttpClient/4.5.x (Java/1.8.0_112)","user":"670603659598","resourcePath":"/messages","httpMethod":"POST","apiId":"jnnd4wh3f8","body":" \"message\" : \"test\" ","isBase64Encoded":false
Fri May 05 16:36:22 UTC 2017 : Endpoint response body before transformations: "errorMessage":"[object Object]"
Fri May 05 16:36:22 UTC 2017 : Endpoint response headers: x-amzn-Remapped-Content-Length=0, x-amzn-RequestId=f91382de-31b0-11e7-bfaa-c7e2e3193355, Connection=keep-alive, Content-Length=34, X-Amz-Function-Error=Handled, Date=Fri, 05 May 2017 16:36:22 GMT, X-Amzn-Trace-Id=root=1-590caa06-47c0526e9aba46d52e47aee5;sampled=0, Content-Type=application/json
Fri May 05 16:36:22 UTC 2017 : Execution failed due to configuration error: Malformed Lambda proxy response
Fri May 05 16:36:22 UTC 2017 : Method completed with status: 502

【问题讨论】:

转换前的端点响应正文:"errorMessage":"[object Object]" - lambda 收到的响应不好。尝试JSON.stringify 传递给回调的响应对象。 @johni 这是响应对象的字符串表示形式: 转换前的端点响应正文: "errorMessage":"\"isBase64Encoded\":false,\"statusCode\":400,\ "headers\":\"Content-Type\":\"application/json\",\"body\":\"message\":\"error\"" 我意识到这里返回了 response_error 对象,我在返回 Missing required key 'Data' in params.Message.Body.Textcode:MissingRequiredParameter 的错误对象上调用了 JSON.stringify,所以这可能是问题的根源 始终序列化您通过 IO(http、磁盘)返回的对象,希望对您有所帮助 感谢您的帮助! 【参考方案1】:

感谢@johni 和@UXDart 的帮助。问题是 api gateway 和 lambda 之间的集成请求正在转换请求正文(您可以找到更多关于这个here)

所以我将处理程序更改为解析 event.body,以便我现在可以从事件中访问正确的数据。 (注意在 lambda 中测试会导致函数超时,因此您需要从 api-gateway 进行测试)

这是我改变的:

exports.handler = (event, context, callback) => 
    const body = JSON.parse(event.body);

    sendEmail(body, function(error, data) 
        if (error) 
           callback(null, response_error);
         else 
           callback(null, response_success);
        
    );
;

【讨论】:

【参考方案2】:

不完全确定,但你应该只返回一个结果,即使是一个错误,因为你正在使用状态码

所以改变回调(response_error);回调(null, response_error);

【讨论】:

对象 errorMessage: ... 是当你返回一个像回调这样的错误时(“这是一个错误消息”),你不想返回你想要返回一个正常的结果像回调(空,结果) 谢谢!这是有道理的,实际上帮助我调试了这个问题。

以上是关于AWS Lambda,API Gateway 返回 Malformed Lambda 代理响应,502 错误的主要内容,如果未能解决你的问题,请参考以下文章