【问题标题】:AWS DynamoDB deleteTable not working when called from NodeJs 8.10 Lambda Function从 NodeJs 8.10 Lambda 函数调用 AWS DynamoDB deleteTable 时不起作用
【发布时间】:2018-11-22 09:18:17
【问题描述】:

作为 Lambda 培训工作的一部分,我正在尝试编写一个通过 API Gateway 触发 Lambda 函数的简单应用程序。然后,该 Lambda 函数通过 AWS 开发工具包连接到 DynamoDB 并尝试删除现有表。

当我对 API Gateway 端点执行 POST 时,Lambda 函数会触发。我收到回复为{},这意味着result 从未重新分配超过初始化值。据我所知,deleteTable 方法永远不会触发。我从未看到存在于回调主体中的console.log()console.error()

请在下面找到详细信息:

设置

Lambda 函数

  • 语言:Node.Js 8.10
  • 触发器:API 网关 POST 端点
  • 执行角色权限:
    • 基本微服务模板(注意:我也尝试为其提供明确的 DynamoDB 完全访问权限,甚至是完全管理员权限;这没有任何帮助。

这是代码。我有更多的事情参与,但当我无法让删除工作时,我将其缩减为:

exports.handler = async (event) => {
    var aws = require('aws-sdk');
    var dynamodb = new aws.DynamoDB();
    
    var params = {
        TableName: "StudyGuideSections"
    };
    
    var result = {};
    
    dynamodb.deleteTable(params, function(err, data) {
        console.log('Entering deleteTable callback...');
        
       if (err) {
           console.log(err, err.stack);
       } else {
           console.log(data);
           
           result = data;
       }
    });
    
    return {
        statusCode: 200,
        "headers": {
            "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(result)
    };
};

API 网关

  • 授权:无
  • 方法:POST

客户端

  • 邮递员(用于测试)
  • 执行$.post的简单Web应用程序

我查看了 CloudWatchX-Ray 日志,没有看到任何错误,也没有看到来自 console.log() 的尝试在deleteTable() 调用的正文中。

此时我几乎要把头发拔掉,因为它阻碍了我的训练。任何帮助将不胜感激。

编辑:为了进一步说明,我可以将返回值的主体更改为“Hello World!”我得到了回应。此外,我可以在deleteTable 调用之前放置一个console.log('Attempting to delete table...");当我这样做时,我会在 CloudWatch 中看到它。我只是从来没有看到来自deleteTable 方法内部的日志。

【问题讨论】:

  • 您是否看到任何日志?你的 lambda 甚至被 GW 调用了吗?
  • 是的,我在 CloudWatch 中看到了日志。日志仅显示通话的开始和结束。如果我将 console.log 放在 deleteTable 之前,我会在 CloudWatch 中看到 console.log 消息。如果我将结果正文更改为“Hello World!”之类的内容,我会在 Postman 的响应中看到该消息。该函数触发,它只是出于某种原因从不调用 deleteTable。
  • 嗯,在函数调用之后,您似乎缺少=>。这就是我的意思:dynamodb.deleteTable(params, function(err, data) =>
  • 嗯...我认为您不能使用那种语法。我必须这样做dynamodb.deleteTable(params, (err, data) => {,我刚刚尝试过,但没有任何区别。
  • 很公平,我的错

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


【解决方案1】:

我终于想通了。因为我使用的是 Node.js 8.10,所以我需要使用 Promise 结构而不是 Callback 结构。

编辑:

正如 Kalev 所提到的,我使用 async 函数作为处理程序的事实是需要使用 await.promise() 而不是我使用 Node.js 8.10 的事实,它仍然支持回调结构。

例如,我需要做一些类似这样的事情,而不是我最初的尝试:

var aws = require('aws-sdk');

exports.handler = async (event) => {
    var ddb = new aws.DynamoDB();

    aws.config.update({
      region: "us-east-1"
    });

    var params = {
        TableName: "StudyGuideSections"
    };

    var result = {}

    try
    {
        result = await ddb.deleteTable(params).promise();
    }
    catch(ex) {
        result = ex;
    }

    return {
        statusCode: 200,
        "headers": {
            "Access-Control-Allow-Origin": "*"
        },
        body: JSON.stringify(result)
    };
};

特别记下result = await ddb.deleteTable(params).promise();,因为那是我搞砸的部分。

【讨论】:

  • 这不是节点 8.10 本身中回调的使用,而是回调和承诺的结合。如果您的函数处理程序不是 async 函数(本质上是 Promise 的语法糖),而是采用传统的回调形式(在 8.10 中受支持),那么它可以正常工作。此外,还有一个配置可确保 lambda 在所有回调都已解决之前不会终止,这可能也有效。
猜你喜欢
  • 1970-01-01
  • 2019-02-13
  • 2019-09-27
  • 2018-05-05
  • 1970-01-01
  • 2016-11-15
  • 2016-11-28
  • 2019-07-27
  • 1970-01-01
相关资源
最近更新 更多