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

MongoDB报Topology was destroyed错误 写入前连接提前关闭原因查询

根本原因

该报错的核心诱因是cursor.forEach不支持等待异步回调执行完成:

  • 不论是JS原生的Array.prototype.forEach还是MongoDB Node.js驱动提供的cursor.forEach,设计上都没有处理返回值为Promise的回调逻辑。你给forEach传入async函数时,它只会按顺序触发每个回调,不会等待回调内部的await异步操作(如代码中的findOne、updateOne)全部执行结束,就会把自身的执行标记为完成
  • 这就导致外层的await cursor.forEach(...)会提前返回,直接执行后续的client.close()关闭数据库连接,此时还在pending状态的updateOne操作失去了可用的数据库连接,最终抛出MongoError: Topology was destroyed错误

修复方案

将游标转为数组后使用for...of遍历,即可正常等待所有异步操作执行完成,同时建议增加try/finally块保证异常场景下连接也能正常关闭:

module.exports.handler = async event => {  
  const client = await MongoClient.connect(
    MONGO_URL,
    { useNewUrlParser: true }
  )
  try {
    const db = client.db()
    // 先将游标转为数组再遍历
    const docs = await db.collection('test').find().project({ _id: 1, pro: 1 }).toArray()
    // for...of 支持正常等待异步操作
    for (const doc of docs) {
      if (!doc.elem) continue
      const data = doc.elem
      for (const provider of data) {
        const exist = await db
          .collection('public_profiles')
          .findOne({ _id: provider.publicProfileID })
        if (_.isEmpty(provider.publicProfileID) || exist === null) {
          await db
            .collection('test')
            .updateOne(
              { _id: doc._id },
              { $pull: { providers: { publicProfileID: provider.publicProfileID } } }
            )
        }
      }
    }
    console.log('providers deleted')
  } finally {
    // 无论执行是否报错都关闭连接,避免连接泄漏
    await client.close()
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 04:42:03