上载到S3的AWS SAM Lambda函数返回无效响应

时间:2019-03-27 14:11:52

标签: node.js amazon-web-services amazon-s3 aws-sam-cli aws-sam

我正在尝试编写一个Lambda函数,以使用AWS SAM将文件上传到S3 ...我正在本地对其进行测试,但似乎没有任何反应,并且lambda函数以无效响应结束。没有其他错误记录。发生了什么事?

这是执行日志:

START RequestId: 71030098-0dd5-1137-0e78-43f1b1671b9c Version: $LATEST
END RequestId: 71030098-0dd5-1137-0e78-43f1b1671b9c
REPORT RequestId: 71030098-0dd5-1137-0e78-43f1b1671b9c  Duration: 2118.53 ms    Billed Duration: 2200 ms    Memory Size: 128 MB Max Memory Used: 46 MB  
2019-03-27 10:59:00 Function returned an invalid response (must include one of: body, headers or statusCode in the response object). Response received: null
2019-03-27 10:59:00 127.0.0.1 - - [27/Mar/2019 10:59:00] "POST /myfunction HTTP/1.1" 502 -

Lambda代码。将上传到S3的文件来自请求正文。

const async = require('async');
const axios = require('axios');
const AWS = require('aws-sdk');
const s3 = new AWS.S3();

const bucketName = process.env.STRINGS_BUCKET_NAME;

exports.lambdaHandler = async (event, context) => {
    let response;

    try {
        const body = JSON.parse(event.body);
        const jsonFilename = new Date().getTime() + '.json';

        async.waterfall([
            function uploadToS3(done) {
                const base64data = new Buffer(body.strings, 'binary');
                s3.putObject({
                        Bucket: bucketName,
                        Key: jsonFilename,
                        Body: base64data,
                    }, (err, success) => {
                        if (err) {
                            console.error(err);
                            throw Error(err);
                        }
                        console.log(success);
                        console.info('File uploaded to S3: ' + jsonFilename);
                        done(null);
                    });
            },
            function doOtherStuff(done) {
                console.log('doOtherStuff');
                done(null);
            }
        ],
            (error) => {
                if (error) {
                    console.error(error);
                    response = {
                        'statusCode': 500,
                        'body': JSON.stringify({
                            statusCode: 500
                        })
                    };
                } else {
                    response = {
                        'statusCode': 200,
                        'body': JSON.stringify({
                            statusCode: 200
                        })
                    };
                }
            });
    } catch (err) {
        console.error(err);
        return err;
    }

    return response
};

我的template.yaml的一部分,其中定义了lambda函数:

Resources:
  UserStringsBucket:
    Type: "AWS::S3::Bucket"
    Properties:
      BucketName: 'mybucket'

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: my-function/
      Handler: app.lambdaHandler
      Runtime: nodejs8.10
      Events:
        MyFunction:
          Type: Api
          Properties:
            Path: /myfunction
            Method: post
      Environment:
        Variables:
          STRINGS_BUCKET_NAME: 'mybucket'
      Policies:
        - AWSLambdaExecute
        - Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Action:
                - s3:PutObject
                - s3:PutObjectACL
              Resource: 'arn:aws:s3:::mybucket/*' 

2 个答案:

答案 0 :(得分:1)

您似乎正在收到此错误,因为您没有等待异步功能完成。您调用async.waterfall,然后有了return response行,并且由于瀑布内部的函数是异步运行的,因此return response首先完成,因此出现Function returned an invalid response错误。

要确认这一点,您可以将let response;行更改为let response = {'statusCode': 200, 'body': 'not yet completed'};,然后查看是否收到此回复。

答案 1 :(得分:0)

@Deiv为我指明了正确的方向。

我必须将函数的签名更改为:

exports.lambdaHandler = (event, context, callback) 

并在瀑布内返回以下响应:

callback(null, response);

我还必须在AWS上手动创建存储桶...我以为SAM会自动执行此操作,但是请确定。