【问题标题】:Query is not working with promise for Dynamo DB查询不适用于 Dynamodb 的承诺
【发布时间】:2022-08-21 01:44:54
【问题描述】:

我有一个发电机数据库表,我可以通过 lambda 使用节点 js 插入数据。我可以从控制台查询,也可以使用 cli 查询。当使用带有 promise 的查询时,它会因调用错误而出错。它没有抛出任何特定的错误。如果我删除承诺并运行,我可以看到与数据库的连接成功。我也试过 ExpressionAttributeValues: { \":name\": {\"S\":id} },

甚至硬编码 id 和相同问题的值。我究竟做错了什么??

import AWS from \"aws-sdk\"
const dyanamoDB = new AWS.DynamoDB.DocumentClient()

AWS.config.update({ region: \"us-east-1\" })
export const checkIFIDExist = async (id) => {

    try {
        const params = {
            ProjectionExpression: \"String1, String2\",
            IndexName: \"String2\",
            KeyConditionExpression: \"String2 = :name\",
            ExpressionAttributeValues: {
                \":name\": id
            },
            TableName: \'my-table\',
        }  
        const data = await dynamoDB.query(params).promise()
        console.log(\"Data:\", data)
        return \"success\"
    }catch (err) {
        throw new Error (`Failed query for ${id} `, err)
    }

}

错误:

2022-08-16T20:24:09.210Z    c2e0c093-2719-48b8-b0bb-4f38de3ac7b6    ERROR   Invoke Error    
{
    \"errorType\": \"Error\",
    \"errorMessage\": \"Failed query for OE0K0I \",
    \"stack\": [
        \"Error: Failed query for OE0K0I \",
        \"    at checkIFStepFunctionIDExists (file:///var/task/src/dynamo-query.js:24:15)\",
        \"    at processTicksAndRejections (internal/process/task_queues.js:95:5)\",
        \"    at async Runtime.handler (file:///var/task/src/index.js:11:19)\"
    ]
}
  • 发生这种情况时err 的内容是什么?将其打印出来并将其添加到您的帖子中。
  • 你真的有一个名为 String2 的索引吗?我的意思是,索引当然不应该只是一个字段名。我可能是在说显而易见的。但只是为了确定。
  • 是 string2 是一个索引
  • @jarmod 错误内容就是我上面的内容。我知道它没有提供太多信息,这就是让我失望的原因。我在另一个项目中实现了相同的查询,我的老队友仍在使用它。我什至引用了旧的 repo 进行比较,并且没有语法差异
  • 请打印err 并将其添加到帖子中。另外,我认为您可能需要更正您对Error() 的使用。而不是简单地将err 作为第二个参数传递,我认为它应该是{ cause: err }

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


【解决方案1】:

如果promise() 函数没有按照您的预期执行。值得注意的是,您实际上也可以使用标准的 Node.js promisify 函数做同样的事情。

import { DocumentClient } from "aws-sdk/clients/dynamodb";
import { promisify } from "util";

const docClient = new AWS.DynamoDB.DocumentClient()
...
const data = await promisify((cb) => docClient.query(params, cb))();

正如@jarmod 指出的那样,可能还有其他事情发生。我添加了一些旁注来澄清一些你可能知道或不知道的事情。

一些旁注

这里只是一些不完全关于主题但可能导致混淆的评论。

// don't do this, it doesn't do what you think it does.
throw new Error(`Failed query for ${id}`, err );

// this prints both a text and an object.
console.error(`Failed query for ${id}`, err);

// this throws just an error with a message
throw new Error(`Failed query for ${id}`);

// there is a 2nd argument which you can pass, which is an "options" parameter, which you can use to send a `cause` along.
throw new Error(`Failed query for ${id}`, { cause: err } );

PS:更多细节可以在in the MDN documentation找到。

我还没有看到你是如何在没有承诺的情况下让它工作的,但如果你这样做了,那就不是你想的那样。

try {
    const params = { ... };
    dynamoDB.query(params);

    // this point is always reached
    return "success"
}catch (err) { 
    // this point is never reached
}

相反,如果没有 Promise,您将不得不使用回调函数。

const params = { ... };
dynamoDB.query(params, (err, data) => {
  if(err) {
    console.error(err);
    return;
  }
  console.log("success", data);
});

【讨论】:

  • 与 SDK 中的本机承诺支持相比,手动承诺 SDK 调用将如何帮助?
  • @jarmod 它不应该有任何区别。但是,发布问题的人似乎表明它在没有.promise() 的情况下也可以工作,这使得通过我在回答中提供的方式手动创建承诺成为一个有用的实验。通过避免看起来被破坏的东西,您可以验证这是否真的是被破坏的东西。
  • 如果没有.promise() 后缀,它就无法工作。 OP错误地假设代码继续返回“成功”的事实意味着它成功了,但事实并非如此。
  • @bvdb,您的答案也与上面打印的错误相同
  • @Shailesh123 正如@jarmod 指出的那样,您确实需要查看err 对象。现在,你并没有真正打印那个错误,它只是被隐藏起来了。此外,@jarmod 指出的是,当您在没有承诺的情况下测试它时,您可能没有正确测试。为了确保,我在我的答案中添加了一些指针以验证这些评论。因为,一旦您查看了 err 消息,它可能就像端点配置不正确或缺少密钥一样简单。
【解决方案2】:

我基本上删除并丢弃了创建新项目的项目,并做了我之前在帖子中提到的相同的事情,而不是在 catch 语句控制台记录它之后抛出错误,我得到了我预期的结果。我真的不知道我之前做错了什么。 @jarmond 我在上面发布的错误,我在更改某些内容时不小心包含了一个依赖项并导致了我提供的错误。感谢大家调查这个问题。

【讨论】:

    猜你喜欢
    • 2020-12-06
    • 2019-11-01
    • 2018-01-06
    • 2017-03-20
    • 2015-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多