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

为何我的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在同一目录下,预期机器人能正常运行

问题原因及解决方法

  1. 核心报错原因:process.env.MONGODB_URI未读取到值,导致传入MongoClient的uri为undefined,触发startsWith调用失败的报错。

  2. .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' });
    
  3. 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);
    });
    
  4. 关于“两次请求同一文件夹”的疑问:大概率是dotenv加载路径错误时,程序同时尝试了默认路径和你指定的错误路径,或者Node.js模块加载机制导致的重复读取,修正.env路径后该现象会消失。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:23:08