【问题标题】:Errors when using a Lambda function to delete a record from dynamoDB, yet record is still deleted使用 Lambda 函数从 dynamoDB 中删除记录时出错,但记录仍被删除
【发布时间】:2019-04-04 11:08:24
【问题描述】:

我正在尝试使用 Lambda 和 API 网关从 DynamoDB 中删除记录。目前记录的Id作为查询参数传递,传递给我的deleteRecord lambda函数,并在documentClient的delete函数中使用。

目前,我在尝试删除记录时收到错误消息,但该记录还是被删除了,我不知道为什么。

在 API 网关上进行测试时,我收到“内部服务器错误”作为响应,但检查表显示该项目已删除,并且日志显示已删除的记录(根据提供 ReturnValues: "ALL_OLD" 在传递给 documentClient 的 params 中)。

直接在 Lambda 上测试时(手动将 ID 插入到我的 dt.delete 函数中),我得到以下信息:

Response:
{
  "errorMessage": "RequestId: xxxxxxxxxxxxxxxxxxxx Process exited before completing request"
}

Request ID:
"xxxxxxxxxxxxxxxxxxxx"

Function Logs:
START RequestId: xxxxxxxxxxxxxxxxxxxx Version: $LATEST
2019-04-04T10:21:55.637Z    xxxxxxxxxxxxxxxxxxxx    Promise { <pending> }
2019-04-04T10:21:55.938Z    xxxxxxxxxxxxxxxxxxxx    TypeError: undefined is not a function
    at Response.<anonymous> (/var/task/deleteTrip.js:28:28)
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:364:18)
    at Request.callListeners (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:105:20)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/sequential_executor.js:77:10)
    at Request.emit (/var/runtime/node_modules/aws-sdk/lib/request.js:683:14)
    at Request.transition (/var/runtime/node_modules/aws-sdk/lib/request.js:22:10)
    at AcceptorStateMachine.runTo (/var/runtime/node_modules/aws-sdk/lib/state_machine.js:14:12)
    at /var/runtime/node_modules/aws-sdk/lib/state_machine.js:26:10
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:38:9)
    at Request.<anonymous> (/var/runtime/node_modules/aws-sdk/lib/request.js:685:12)
END RequestId: xxxxxxxxxxxxxxxxxxxx
REPORT RequestId: xxxxxxxxxxxxxxxxxxxx  Duration: 941.48 ms Billed Duration: 1000 ms    Memory Size: 128 MB Max Memory Used: 67 MB  
RequestId: xxxxxxxxxxxxxxxxxxxx Process exited before completing request

尽管出现了错误,但在这种情况下,记录也会从表中删除。

我已经按照DocumentClient documentation 删除了一条记录,但是它没有解释如何回传响应(而只是记录来自回调的数据),所以我不确定这是否是我的问题。

Lambda 函数
索引.js:

const deleteTrip = require('./deleteTrip.js');
const dt = new deleteTrip();

exports.handler = async (event) => {
    return dt.delete(event.queryStringParameters['Id']);
};

deleteTrip.js:

const AWS = require('aws-sdk');

let documentClient = new AWS.DynamoDB.DocumentClient({
    'region': 'eu-west-1'
});

module.exports = class deleteTrip {
    delete(Id) {
        return new Promise((resolve, reject) => {
            if (typeof Id !== 'string') throw `Expected: "String", received: ${typeof Id}`;
            let params = {
                TableName: "xyzDataTable",
                Key: {
                    tripId: Id
                },
                ReturnValues: "ALL_OLD",
                Exists: true
            };
            documentClient.delete(params, function(err, data) {
                if (err) {
                    console.log("Error deleting record from dynamoDB:", err);
                    console.log(params);
                    return reject(err);
                } else {
                    return resolve(...data.Attributes);
                }
            })
        });

    }
}

如果请求成功,我希望返回已删除项目的详细信息,否则会抛出错误。

【问题讨论】:

  • 所有 SDK 函数都有一个 .promise() 方法,您可以使用它来代替使用回调和制造您自己的 Promise。例如:rsp = await documentClient.delete(...).promise()
  • 这是在 new Promise 内还是代替?当我立即在 delete 函数中尝试此操作时,当与 await 一起使用时,我得到 Parsing error: unexpected token documentClient

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


【解决方案1】:

下面是一个如何将 Promise 与 DynamoDB DocumentClient(或者实际上是较低级别的 DynamoDB API)一起使用的示例:

const AWS = require('aws-sdk');

let documentClient = new AWS.DynamoDB.DocumentClient({
    'region': 'eu-west-1'
});

class deleteTrip {
    delete(Id) {
        const params = {
            TableName: "xyzDataTable",
            Key: {
                tripId: Id
            },
            ReturnValues: "ALL_OLD",
            Exists: true
        };
        return documentClient.delete(params).promise();
    }
}

const testing = async (id) => {
    try {
        const dt = new deleteTrip();
        const data = await dt.delete(id);
        console.log("Success:", data);

    } catch(err) {
        console.log("Error:", err);
    }
}

testing(101);

还请注意,如果您尝试删除不存在的项目,删除操作将成功,即不会报告任何错误。这被视为成功,这正是 DynamoDB 的本质。

【讨论】:

    【解决方案2】:

    在 Lambda 中,只要导出的处理程序返回一个值,该函数就会退出。您正在返回一个承诺,并且该过程甚至在它解决之前就退出了。

    在 index.js 中进行以下更改

    const deleteTrip = require('./deleteTrip.js');
    const dt = new deleteTrip();
    
    exports.handler = async (event) => {
        try{
            var result = await dt.delete(event.queryStringParameters['Id']);
            return res;
        }
        catch(err){
            //if the delete function throws an error or the promise rejects
            return err;
        }
    };
    

    【讨论】:

    • 已更新代码以反映这一点,但我仍然收到 undefined is not a function 错误,显然源自 deleteTrip 的 return resolve(...data.Attributes) 行。 js.
    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多