带有 API 网关和 Node.js 的 AWS Lambda 返回 HTTP 502
2022-02-03
1085
我正在测试 AWS Lambda 和 API 网关之间的功能。我的 lambda 函数正在使用一个节点,并且我已经定义了想要从 S3 中提取的参数。这是我的 lambda:
console.log('Loading function');
const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
exports.handler = async (event, context) => {
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
const params = {
Bucket: 'testing-api-lambda-s3-jfr',
Key: 'sample-file-testing.csv',
};
exports.sendRes = (body, status = 200) => {
const response = {
statusCode: status,
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(body)
};
return response;
};
lambda 上的测试事件返回 OK,所以我认为 lambda 没问题:
Test Event Name
test
Response
"text/csv"
Function Logs
START RequestId: 07d8ea41-976b-4e49-9fb7-ccfafca15dcf Version: $LATEST
2022-02-03T19:38:46.871Z 07d8ea41-976b-4e49-9fb7-ccfafca15dcf INFO CONTENT TYPE: text/csv
END RequestId: 07d8ea41-976b-4e49-9fb7-ccfafca15dcf
REPORT RequestId: 07d8ea41-976b-4e49-9fb7-ccfafca15dcf Duration: 499.10 ms Billed Duration: 500 ms Memory Size: 128 MB Max Memory Used: 80 MB
Request ID
07d8ea41-976b-4e49-9fb7-ccfafca15dcf
在我的 API 网关上,我将其配置为 GET,没有定义查询字符串或路径参数:
测试时错误为:
{
"message": "Internal server error"
}
完整 API 网关执行日志:
Execution log for request 2866b8b2-bd57-49f7-aad9-1a9279612364
Thu Feb 03 19:44:42 UTC 2022 : Starting execution for request: 2866b8b2-bd57-49f7-aad9-1a9279612364
Thu Feb 03 19:44:42 UTC 2022 : HTTP Method: GET, Resource Path: /
Thu Feb 03 19:44:42 UTC 2022 : Method request path: {}
Thu Feb 03 19:44:42 UTC 2022 : Method request query string: {}
Thu Feb 03 19:44:42 UTC 2022 : Method request headers: {}
Thu Feb 03 19:44:42 UTC 2022 : Method request body before transformations:
Thu Feb 03 19:44:42 UTC 2022 : Endpoint request URI: https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:143578772304:function:getObjectNode/invocations
Thu Feb 03 19:44:42 UTC 2022 : Endpoint request headers: {X-Amz-Date=20220203T194442Z, x-amzn-apigateway-api-id=vzcwgufch1, Accept=application/json, User-Agent=AmazonAPIGateway_vzcwgufch1, Host=lambda.us-east-1.amazonaws.com, X-Amz-Content-Sha256=ec78e1a3cab036558869aced97bcd18b2213fcab99c7a38ddc15d6bf509a5f5b, X-Amzn-Trace-Id=Root=1-61fc30aa-f6d4b97e6327eed29d022b45, x-amzn-lambda-integration-tag=2866b8b2-bd57-49f7-aad9-1a9279612364, Authorization=*********************************************************************************************************************************************************************************************************************************************************************************************************************************************a0c1a3, X-Amz-Source-Arn=arn:aws:execute-api:us-east-1:143578772304:vzcwgufch1/test-invoke-stage/GET/, X-Amz-Security-Token=IQoJb3JpZ2luX2VjEEQaCXVzLWVhc3QtMSJIMEYCIQDE4SYIymD/u99+1dzLRSk8U+DbUxCC9ygNy6aYr1SjhQIhAN9P2Oh/UyQl1L0mLSNTGhNRFGz2G5irLwGI7gHbs/4eKvoDCHwQABoMM [TRUNCATED]
Thu Feb 03 19:44:42 UTC 2022 : Endpoint request body after transformations: {"resource":"/","path":"/","httpMethod":"GET","headers":null,"multiValueHeaders":null,"queryStringParameters":null,"multiValueQueryStringParameters":null,"pathParameters":null,"stageVariables":null,"requestContext":{"resourceId":"dw7k4w6igh","resourcePath":"/","httpMethod":"GET","extendedRequestId":"M-yKsEC5IAMFegA=","requestTime":"03/Feb/2022:19:44:42 +0000","path":"/","accountId":"143578772304","protocol":"HTTP/1.1","stage":"test-invoke-stage","domainPrefix":"testPrefix","requestTimeEpoch":1643917482625,"requestId":"2866b8b2-bd57-49f7-aad9-1a9279612364","identity":{"cognitoIdentityPoolId":null,"cognitoIdentityId":null,"apiKey":"test-invoke-api-key","principalOrgId":null,"cognitoAuthenticationType":null,"userArn":"arn:aws:iam::143578772304:user/fernando","apiKeyId":"test-invoke-api-key-id","userAgent":"aws-internal/3 aws-sdk-java/1.12.138 Linux/5.4.156-94.273.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.312-b07 java/1.8.0_312 vendor/Oracle_Corporation cfg/retry-mod [TRUNCATED]
Thu Feb 03 19:44:42 UTC 2022 : Sending request to https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:us-east-1:143578772304:function:getObjectNode/invocations
Thu Feb 03 19:44:42 UTC 2022 : Received response. Status: 200, Integration latency: 24 ms
Thu Feb 03 19:44:42 UTC 2022 : Endpoint response headers: {Date=Thu, 03 Feb 2022 19:44:42 GMT, Content-Type=application/json, Content-Length=261, Connection=keep-alive, x-amzn-RequestId=62424064-5199-48b7-ad4e-f8976d86e514, X-Amz-Function-Error=Unhandled, x-amzn-Remapped-Content-Length=0, X-Amz-Executed-Version=$LATEST, X-Amzn-Trace-Id=root=1-61fc30aa-f6d4b97e6327eed29d022b45;sampled=0}
Thu Feb 03 19:44:42 UTC 2022 : Endpoint response body before transformations: {"errorType":"TypeError","errorMessage":"Cannot read property '0' of undefined","trace":["TypeError: Cannot read property '0' of undefined"," at Runtime.exports.handler (/var/task/index.js:12:33)"," at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"]}
Thu Feb 03 19:44:42 UTC 2022 : Lambda execution failed with status 200 due to customer function error: Cannot read property '0' of undefined. Lambda request id: 62424064-5199-48b7-ad4e-f8976d86e514
Thu Feb 03 19:44:42 UTC 2022 : Method completed with status: 502
有什么建议吗?谢谢
2个回答
执行日志中的错误消息表明
event
对象没有包含一些 bucket 信息的数组
Records
。原因是 API Gateway 请求事件没有此数组。只要您不在 REST 请求正文中传递存储桶信息,API 网关就不会对您的存储桶执行任何操作。
此外,您期望使用以下行从 API 网关请求中获取存储桶名称和密钥:
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
但您从未在任何地方真正使用过这些变量,本质上是使用以下行硬编码您自己的存储桶名称和密钥:
const params = {
Bucket: 'testing-api-lambda-s3-jfr',
Key: 'sample-file-testing.csv',
};
如果不需要这两行,只需从代码中删除它们即可。
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
我觉得您对 Lambda 由 S3 事件触发时的
event
对象应该是什么样子感到困惑,与 Lambda 由 API 网关代理集成触发时的样子相比。如果您想知道当 API 网关调用
event
对象时该对象是如何构造的,您可能需要查看 AWS 文档中的此
页面
。
Ervin Szilagyi
2022-02-03
根据执行日志,您的 API 网关无法转换从 lambda 收到的响应。
您需要为您的 API 提供一个定义响应结构的模型,以便它可以转换响应。 这属于映射模板。
Lunarantic
2022-02-04