为何我的Discord机器人重复请求文件夹且启动时MongoDB报错?
Discord机器人启动报错:MongoDB连接字符串未定义及.env加载问题
我正在开发一个具备封禁(ban)、踢出(kick)、用户信息查询功能的私人Discord机器人,但启动时触发报错,同时疑惑机器人为何会两次请求同一个文件夹。
报错日志
PS D:\Rubytoolbot> node index.js Debugger attached. Waiting for the debugger to disconnect... D:\Rubytoolbot\node_modules\mongodb-connection-string-url\lib\index.js:9 return (connectionString.startsWith('mongodb://') || ^ TypeError: Cannot read properties of undefined (reading 'startsWith') at connectionStringHasValidScheme (D:\Rubytoolbot\node_modules\mongodb-connection-string-url\lib\index.js:9:30) at new ConnectionString (D:\Rubytoolbot\node_modules\mongodb-connection-string-url\lib\index.js:85:34) at parseOptions (D:\Rubytoolbot\node_modules\mongodb\lib\connection_string.js:192:17) at new MongoClient (D:\Rubytoolbot\node_modules\mongodb\lib\mongo_client.js:52:63) at Object.<anonymous> (D:\Rubytoolbot\index.js:79:21) at Module._compile (node:internal/modules/cjs/loader:1368:14) at Module._extensions..js (node:internal/modules/cjs/loader:1426:10) at Module.load (node:internal/modules/cjs/loader:1205:32) at Module._load (node:internal/modules/cjs/loader:1021:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:142:12) Node.js v21.7.2
相关代码片段
顶部依赖加载代码
require('dotenv').config({ path: './Rubytoolbot/.env' }) //uses custom location const fs = require("fs"); const { Client, Collection, GatewayIntentBits, ActivityType } = require("discord.js"); const { MongoClient } = require('mongodb'); // Import MongoClient from mongodb package const http = require('http'); const https = require('https');
MongoDB相关代码
// MongoDB configuration const uri = process.env.MONGODB_URI; const mongoClient = new MongoClient(uri, { useNewUrlParser: true, useUnifiedTopology: true }); // When the bot is added to a new server client.on("guildCreate", async (guild) => { console.log(`Added to guild: ${guild.name} (ID: ${guild.id})`); try { await mongoClient.connect(); const database = mongoClient.db('bot_db'); // Change to your desired database name const collection = database.collection('guilds'); // Insert the guild ID and name into the collection await collection.insertOne({ guildId: guild.id, guildName: guild.name }); } catch (error) { console.error("Error adding guild to MongoDB:", error); } finally { await mongoClient.close(); } }); // When the bot is removed from a server client.on("guildDelete", async (guild) => { console.log(`Removed from guild: ${guild.name} (ID: ${guild.id})`); try { await mongoClient.connect(); const database = mongoClient.db('bot_db'); // Change to your desired database name const collection = database.collection('guilds'); // Remove the guild ID from the collection await collection.deleteOne({ guildId: guild.id }); } catch (error) { console.error("Error removing guild from MongoDB:", error); } finally { await mongoClient.close(); } });
已尝试操作
- 将
require("dotenv").config();修改为require('dotenv').config({ path: './Rubytoolbot/.env' })指定自定义路径,但问题依旧 - .env文件与index.js在同一目录下,预期机器人能正常运行
问题原因及解决方法
核心报错原因:
process.env.MONGODB_URI未读取到值,导致传入MongoClient的uri为undefined,触发startsWith调用失败的报错。.env路径修正:你的index.js在
D:\Rubytoolbot目录下,指定path: './Rubytoolbot/.env'会让程序去D:\Rubytoolbot\Rubytoolbot\.env找文件,显然不存在。推荐两种可靠写法:// 写法1:dotenv默认加载当前执行目录的.env,直接省略path参数 require('dotenv').config(); // 写法2:用__dirname精准定位当前文件目录下的.env(更稳妥) require('dotenv').config({ path: __dirname + '/.env' });MongoClient连接优化:你在
guildCreate和guildDelete事件中每次都关闭连接,后续事件触发时会因为客户端已关闭而报错。建议全局只连接一次MongoDB:// 全局连接MongoDB,启动时执行 async function connectMongo() { try { await mongoClient.connect(); console.log("Connected to MongoDB successfully"); } catch (err) { console.error("MongoDB connection failed:", err); process.exit(1); // 连接失败直接退出程序 } } // 在Bot登录后执行MongoDB连接 client.login(process.env.DISCORD_TOKEN).then(() => { connectMongo(); }); // 修改事件代码,不再关闭连接 client.on("guildCreate", async (guild) => { console.log(`Added to guild: ${guild.name} (ID: ${guild.id})`); try { const database = mongoClient.db('bot_db'); const collection = database.collection('guilds'); await collection.insertOne({ guildId: guild.id, guildName: guild.name }); } catch (error) { console.error("Error adding guild to MongoDB:", error); } }); client.on("guildDelete", async (guild) => { console.log(`Removed from guild: ${guild.name} (ID: ${guild.id})`); try { const database = mongoClient.db('bot_db'); const collection = database.collection('guilds'); await collection.deleteOne({ guildId: guild.id }); } catch (error) { console.error("Error removing guild from MongoDB:", error); } }); // 程序退出时关闭MongoDB连接 process.on('SIGINT', async () => { await mongoClient.close(); console.log("MongoDB connection closed"); process.exit(0); });关于“两次请求同一文件夹”的疑问:大概率是dotenv加载路径错误时,程序同时尝试了默认路径和你指定的错误路径,或者Node.js模块加载机制导致的重复读取,修正.env路径后该现象会消失。
内容的提问来源于stack exchange,提问作者Sapphire Shork
相关产品推荐
相关产品推荐

