开发者问题收集

带有 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,没有定义查询字符串或路径参数: enter image description here

测试时错误为:

{
  "message": "Internal server error"
}

enter image description here

完整 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 提供一个定义响应结构的模型,以便它可以转换响应。 这属于映射模板。

https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-gateway-response-using-the-console.html

Lunarantic
2022-02-04