【问题标题】:Lambda function errorMessage": "Cannot read property 'bucket' of undefinedLambda 函数 errorMessage”:“无法读取未定义的属性 'bucket'
【发布时间】:2020-05-29 17:47:36
【问题描述】:

我有一个 lambda 函数,只要有东西保存在我的 s3 存储桶中就会触发,

目的是读取 JSON 文件的元数据并在 dynamoDB 表中插入行;

例如 培训期从 6 月 1 日开始,6 月 8 日结束 培训日为周一、周三和周五 因此 lambda 应该插入 4 行(6 月 1 日、3 日、5 日、8 日)

到目前为止只插入了一行,然后发生错误并崩溃

该功能触发良好,但有时会出现此错误消息。

{
    "errorType": "TypeError",
    "errorMessage": "Cannot read property 'bucket' of undefined",
    "stack": [
        "TypeError: Cannot read property 'bucket' of undefined",
        "    at Runtime.exports.handler (/var/task/index.js:26:44)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

这是我的功能

let AWS = require('aws-sdk');
let s3 = new AWS.S3();
let moment = require('moment');
let uuid = require('node-uuid');

let apiSportmTrainingTableName = process.env.API_SPORTM_TRAININGTABLE_NAME
let dynamodb = new AWS.DynamoDB.DocumentClient();


exports.handler =  async (event, context) => {
  //eslint-disable-line
  const Bucket = await event.Records[0].s3.bucket.name;

  const Key = await event.Records[0].s3.object.key;
  const objectHead = await s3.headObject({Bucket, Key}).promise();

  let start = moment(new Date(objectHead.Metadata.trainingstart), "YYYY-MM-DD");
  let end = moment(new Date(objectHead.Metadata.trainingend), "YYYY-MM-DD");
  let days = JSON.parse("[" + objectHead.Metadata.trainingdays + "]");

  try {
    for (let m = moment(start); m.diff(end, 'days') <= 0; m.add(1, 'days')) {

      for (const e of days) {

        if (moment(m).day() === e) {
          let params = {
            TableName: apiSportmTrainingTableName,
            Item: {
              "id": uuid.v1(),
              "trainingDate": moment(m).format('YYYY-MM-DD'),
              "statut": true,
              "athleteCategory": objectHead.Metadata.trainingmembercategory,
              "trainingTime": objectHead.Metadata.trainingtime
            }
          };
          return await dynamodb.put(params).promise();
        }
      }
    }
  } catch (err) {
    console.error('Error', err);
    return;
  }
  context.done(null, 'Successfully processed DynamoDB record'); // SUCCESS with message
};

当事件记录时它看起来像那样

Records: [
    {
      eventVersion: '2.1',
      eventSource: 'aws:s3',
      awsRegion: 'us-east-1',
      eventTime: '2020-05-29T18:34:53.250Z',
      eventName: 'ObjectCreated:Put',
      userIdentity: [Object],
      requestParameters: [Object],
      responseElements: [Object],
      s3: [Object]
    }
  ]
}
```

that a part of logs it fails and then works and then it keeps trying and fail




[logs][1]


  [1]: https://i.stack.imgur.com/Sj5C7.png

【问题讨论】:

  • 不要await 存储桶名称和密钥。它们不是返回承诺的函数。它们是具有属性的简单对象。不要return await xyz.promise(),只要await xyz.promise()

标签: node.js amazon-web-services amazon-s3 aws-lambda aws-amplify


【解决方案1】:

您在将数据插入 DynamoDB 后使用return

return await dynamodb.put(params).promise();

这会将 DynamoDB 操作的结果作为 Lambda 函数的结果返回,该函数终止了执行。这解释了为什么只有一条记录插入到 DynamoDB 中。我会尝试删除 return 并查看是否也删除了错误(我的最佳猜测:返回的值会以某种方式导致另一个执行,但这次缺少 S3 事件,因此 event.Records[0].s3 将是未定义的)。

【讨论】:

  • 嗨,谢谢,我刚试过;删除返回修复插入数据库的问题,但在日志中我仍然有“errorMessage”:“无法读取未定义的属性'bucket'”,
  • 错误是在同一次执行过程中出现,还是在另外一个执行过程中出现?您还可以记录(仅用于调试)完整事件以查看其中的内容吗?
  • 所以首先触发该函数,然后发生错误,然后它会在某个时候一次又一次地执行它,它会在数据库中插入所有数据,但然后它会再次尝试,我会将日志放在问题
  • 我修复了它,在 for of 循环的 and 处添加了一个返回
猜你喜欢
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2018-10-30
相关资源
最近更新 更多