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 错误的主要内容,如果未能解决你的问题,请参考以下文章

AWS API Gateway OPTIONS 请求返回 500 错误

具有 Cognito 身份验证的 AWS API Gateway Lambda 函数返回 415 Unsupported Media Type

使用代理通过 AWS API Gateway 的 Lambda 错误

AWS API Gateway + AWS Lambda 中的 CORS

从AWS API-Gateway中找出lambda名称

AWS API Gateway 的访问权限