开发Discord Bot时遭遇MongoDB的BSONError循环依赖问题求助
BSONError: cyclic dependency detected(MongoDB原生驱动场景)
问题场景
开发Discord Bot过程中,使用MongoDB原生驱动操作数据库时,突然抛出BSONError: cyclic dependency detected错误。搜索发现现有公开解决方案大多针对Mongoose框架,针对原生驱动的排查思路极少,多方调试仍无法定位根因。
核心代码
业务逻辑代码片段
async start (recall: boolean = false) { console.log('Starting server...'); if (recall && !this.started) { // ... } else if (this.started) { // ... } else if (!this.database) { // ... } else { let { connections } = this; connections = connections.map((connection: any) => { const userStyle = parseInt(connection?.user?.style) || 0; const userXp = parseInt(connection?.user?.xp) || 0; const userPrevWars = Math.max(parseInt(connection?.user?.prevWars.length) || 0, 1); const userLevel = XPtoLevel(userXp); const parser = LeveltoXP(userXp); const Rate = [Math.pow(userPrevWars, 1.125),Math.pow(userStyle, 0.875)]; const userPower = Math.max( (Math.sqrt(100 + 8 * userXp) * Rate[0] * userStyle * (parser + userXp)) / 26 * parser * Rate[1], 1 ); return { ...connection, user: { ...connection.user, power: userPower } }; }); const avarage = connections.reduce((a,b) => a + (b?.user.power || 0)) / connections.length; const pointerPower = avarage * Math.random() / 2 + avarage / 2; connections?.forEach(async (connection: any, index: number) => { const current = connection.user.power; const enemy = connections[([1,0])[index]].user.power; const chance = current / (current + enemy); const win = pointerPower < current; connection?.message?.reply('The match is starting! Please wait...'); setTimeout(() => { connection?.message?.reply(`Your power is ${current}, enemy power is ${enemy}. \n Your chance to win is ${Math.round(chance * 10) * 10}%`); setTimeout(async () => { connection?.message?.reply(`You ${win ? 'win' : 'lost'} the match!`); connection.user.xp += Math.max( 10, Math.floor(Math.round( Math.abs(current - enemy) * enemy / current * (win ? 1 : 0.5) ) * 100) / 100 ); connection.user.prevWars.push({ user: connection.user, result: 'win', time: new Date().getTime(), xp: connection.user.xp, enemy }); console.log(connection.user); await this.database.updateOne({ id: connection.user.id }, { $set: { xp: connection.user.xp, prevWars: connection.user.prevWars } }); this.removeConnection(connection); }, 3000); }, 1000) }); } } else { ... } }
MongoDB原生驱动连接代码(mongo.ts)
import { MongoClient } from "mongodb"; class Database { constructor (url: any, dbName: any) { this.url = url; this.mongo = new MongoClient(url); this.database = null; this.databaseConnection = null; this.dbName = dbName; this.connect(); } async connect() { this.database = await this.mongo.connect(); this.databaseConnection = this.database.db(this.dbName); console.log(`Connected to ${this.dbName}`); } async disconnect() { await this.mongo.close(); } async getCollection(name: string) { const collection = this.databaseConnection.collection(name); return collection; } url: any; mongo: any; database: any; databaseConnection: any; dbName: any; } export default Database;
报错信息
super(message); ^ BSONError: cyclic dependency detected at new BSONError (C:\Users\...\node_modules\bson\src\error.ts:4:5) at serializeObject (C:\Users\...\node_modules\bson\src\parser\serializer.ts:373:34) at serializeInto (C:\Users\...\node_modules\bson\src\parser\serializer.ts:1013:17) at serializeObject (C:\Users\...\node_modules\bson\src\parser\serializer.ts:387:20) at serializeInto (C:\Users\...\node_modules\bson\src\parser\serializer.ts:1013:17) at serializeObject (C:\Users\...\node_modules\bson\src\parser\serializer.ts:387:20) at serializeInto (C:\Users\...\node_modules\bson\src\parser\serializer.ts:802:17) at serializeObject (C:\Users\...\node_modules\bson\src\parser\serializer.ts:387:20) at serializeInto (C:\Users\...\node_modules\bson\src\parser\serializer.ts:1013:17) at serializeObject (C:\Users\...\node_modules\bson\src\parser\serializer.ts:387:20)
解决方法
放弃MongoDB原生驱动,改用mongoose框架替代,错误直接消失,同时Mongoose的封装特性也提升了开发效率。
内容的提问来源于stack exchange,提问作者Wraith
相关产品推荐
相关产品推荐

