You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Promise调用DynamoDB documentClient.get()时部分哈希键查询失败

DynamoDB documentClient.get() 混合回调与Promise时部分哈希键查询失败问题分析

问题背景

使用AWS SDK的documentClient.get()查询DynamoDB时,出现查询结果不一致的情况:

  • 手动在AWS控制台创建的条目(db1001、db1013)可查询成功
  • 通过AWS SDK写入的条目(db1002至db1012)查询失败
  • 同时传入回调函数并调用.promise()时触发错误,移除.promise()仅用回调、或仅用.promise()时所有查询均正常

原始代码

let fetchOneByKey = async (collection_name, entry_id) => {
    console.log('fetching table:', collection_name, "using key:", entry_id);
    var params = {
        TableName: collection_name || 'Lifestyle',
        Key: {"entry_id": entry_id}
    };
    
   let payload = await docClient.get(params,(err, data)=>{
        if(err){
            console.log('err::',err)
        } else {
            console.log('data::',data)
        }
   }).promise();
    return payload;
}

报错信息

fetching table: lifestyle-dictionary using key: db1002
err:: Error [TypeError]: Cannot read properties of undefined (reading 'push')
    at Request.HTTP_DATA (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/event_listeners.js:499:35)
    at Request.callListeners (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/request.js:686:14)
    at IncomingMessage.onReadable (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/event_listeners.js:399:32)
    at IncomingMessage.emit (node:events:513:28)
    at IncomingMessage.emit (node:domain:489:12)
    at emitReadable_ (node:internal/streams/readable:590:12)
    at onEofChunk (node:internal/streams/readable:568:5)
    at readableAddChunk (node:internal/streams/readable:275:5) {
  code: 'TypeError',
  time: 2023-02-07T07:41:18.876Z,
  statusCode: 200,
  retryable: false,
  retryDelay: 31.881162055453217
}
node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

Error [TypeError]: Cannot read properties of undefined (reading 'push')
    at Request.HTTP_DATA (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/event_listeners.js:499:35)
    at Request.callListeners (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/sequential_executor.js:106:20)
    at Request.emit (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/sequential_executor.js:78:10)
    at Request.emit (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/request.js:686:14)
    at IncomingMessage.onReadable (/Users/gazakorompis/snow-react/app-lifestyle/dynamodb/node_modules/aws-sdk/lib/event_listeners.js:399:32)
    at IncomingMessage.emit (node:events:513:28)
    at IncomingMessage.emit (node:domain:489:12)
    at emitReadable_ (node:internal/streams/readable:590:12)
    at onEofChunk (node:internal/streams/readable:568:5)
    at readableAddChunk (node:internal/streams/readable:275:5) {
  code: 'TypeError',
  time: 2023-02-07T07:41:18.876Z,
  statusCode: 200,
  retryable: false,
  retryDelay: 31.881162055453217
}

Node.js v18.7.0

关键现象总结

  • 手动创建的条目查询成功,SDK写入的条目查询失败:手动创建的数据结构简单,响应处理时未触发内部逻辑冲突;SDK写入的数据可能包含更多字段或不同序列化格式,触发了错误
  • 同时使用回调和.promise()时出现错误,单独使用其中一种方式则完全正常

原因分析

AWS SDK v2的设计规则是不允许同时为请求传入回调函数并调用.promise()。这两种模式会初始化两套独立的响应处理逻辑,导致内部事件监听和数据收集状态混乱:

  • 回调模式会注册HTTP_DATA事件监听来收集响应数据
  • Promise模式也会注册自己的事件处理逻辑
    两者竞争处理响应流时,会导致某个用于存储数据的数组未被正确初始化,进而抛出Cannot read properties of undefined (reading 'push')的类型错误。

解决方案

方案1:仅使用Promise模式(推荐)

移除回调函数,仅通过.promise()配合async/await处理异步逻辑,这是现代Node.js代码的最佳实践:

let fetchOneByKey = async (collection_name, entry_id) => {
    console.log('fetching table:', collection_name, "using key:", entry_id);
    var params = {
        TableName: collection_name || 'Lifestyle',
        Key: {"entry_id": entry_id}
    };
    
    try {
        const payload = await docClient.get(params).promise();
        console.log('data::', payload);
        return payload;
    } catch (err) {
        console.log('err::', err);
        throw err; // 根据业务需求选择是否抛出错误
    }
}

方案2:仅使用回调模式

如果需要保留回调写法,不要调用.promise():

let fetchOneByKey = (collection_name, entry_id, callback) => {
    console.log('fetching table:', collection_name, "using key:", entry_id);
    var params = {
        TableName: collection_name || 'Lifestyle',
        Key: {"entry_id": entry_id}
    };
    
    docClient.get(params, (err, data) => {
        if (err) {
            console.log('err::', err);
            callback(err);
        } else {
            console.log('data::', data);
            callback(null, data);
        }
    });
}

内容的提问来源于stack exchange,提问作者gfek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 21:01:44