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

使用nedb数据库无递归却报Maximum call stack size exceeded错误如何解决

问题根因

这个RangeError不是你写了显式递归逻辑,是nedb内置的深拷贝函数在序列化待插入数据时,遇到了带循环引用的对象,触发了无限递归导致爆栈。nedb在插入数据前会对数据做深拷贝,碰到a.b = a这类互相引用的结构时,递归就不会停止,直接触发栈溢出。

排查步骤
  • 先校验待插入对象是否存在循环引用:在调用db.insert(updateData)前添加一行测试代码console.log(JSON.stringify(updateData)),如果这一步直接抛出Converting circular structure to JSON的错误,即可确认是待插入数据的问题。
  • 逐个检查updateData的字段值:重点排查key和args[0]两个变量,你是不是直接把Discord.js返回的Message、User、Guild这类框架内置对象直接赋值给了这两个变量?这类对象本身内部存在大量循环引用(比如message.author.message会指回原message对象),直接存入数据库就会触发报错。
  • 检查未展示的findInList函数逻辑:确认该函数是否存在和findPlayer互相调用的逻辑,比如findInList回调里触发findPlayer,findPlayer回调里又触发findInList,满足触发条件的情况下就会形成隐式的回调递归。
  • 对比你能正常入库的命令的插入逻辑,看两个场景下插入的字段值有什么差异,重点看是不是正常入库的代码里只存了字符串、数字这类基础类型,而出错的代码里存了对象。
修复方案
  • 所有存入nedb的字段都只保留基础类型,不要直接存储框架返回的实例对象:比如要存用户ID就取message.author.id(字符串类型),要存用户名就取message.author.username,不要把整个message.author对象直接赋值给key。
  • 手动提取需要存储的属性,避免未知属性被加入插入对象,示例如下:
// 修正后的赋值逻辑
let updateData = {
  name: key.toString(), // 确保key是纯字符串
  display: args[0].trim(), // 确保args[0]是纯文本
  socialCredit: 0,
  games: []
}
  • 调整回调执行顺序,避免隐式递归:可以把findInList的逻辑放到db.insert的成功回调里执行,确保插入完成后再更新列表,避免异步逻辑互相触发:
db.insert(updateData,function(err,newDoc){
  if(err) return console.log(err)
  message.reply("Added you to the database.")
  // 插入成功后再操作列表
  findInList(key, function(users){
    if(!users[0]) {
      db.update({name:'list'},{$push:{list:key}},{},function(){});
    }
  })
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 11:15:05