AWS SAM Lambda 函数上传到 S3 returns 无效响应
AWS SAM Lambda function to upload to S3 returns invalid response
我正在尝试使用 AWS SAM 编写一个 Lambda 函数来将文件上传到 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
};
我定义 lambda 函数的 template.yaml 的一部分:
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/*'
您收到此错误似乎是因为您没有等待异步函数完成。你调用 async.waterfall,然后你有你的 return response
行,并且因为瀑布中的函数 运行 异步,你的 return response
首先完成,因此 Function returned an invalid response
错误。
要确认这一点,您可以将 let response;
行更改为 let response = {'statusCode': 200, 'body': 'not yet completed'};
,然后查看是否收到此响应。
@Deiv 指出了正确的方向。
我必须将函数的签名更改为:
exports.lambdaHandler = (event, context, callback)
并在瀑布内返回响应:
callback(null, response);
我还必须在 AWS 上手动创建存储桶...我以为 SAM 会自动执行此操作,但请想想看。
我正在尝试使用 AWS SAM 编写一个 Lambda 函数来将文件上传到 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
};
我定义 lambda 函数的 template.yaml 的一部分:
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/*'
您收到此错误似乎是因为您没有等待异步函数完成。你调用 async.waterfall,然后你有你的 return response
行,并且因为瀑布中的函数 运行 异步,你的 return response
首先完成,因此 Function returned an invalid response
错误。
要确认这一点,您可以将 let response;
行更改为 let response = {'statusCode': 200, 'body': 'not yet completed'};
,然后查看是否收到此响应。
@Deiv 指出了正确的方向。
我必须将函数的签名更改为:
exports.lambdaHandler = (event, context, callback)
并在瀑布内返回响应:
callback(null, response);
我还必须在 AWS 上手动创建存储桶...我以为 SAM 会自动执行此操作,但请想想看。