使用Mongoose操作MongoDB Atlas时model.save()无响应无报错如何解决
问题排查与解决方案
1. 修复Mongoose连接逻辑的错误捕获
你当前的try/catch完全无法捕获连接错误,因为mongoose.connect是异步方法,同步的try/catch抓不到异步异常,连接失败时你根本感知不到,后续数据库操作会一直处于pending状态,看起来就是无响应无报错。
修正后的初始化代码:
const mongoose = require('mongoose'); async function initMongoose() { try { await mongoose.connect( process.env.mongourl, { useNewUrlParser: true, useUnifiedTopology: true } ); console.log("Mongoose is connected"); } catch (e) { console.error("Mongoose could not connect:", e); } } // 额外监听全局连接错误,避免遗漏异常 mongoose.connection.on('error', err => { console.error('Mongoose connection error:', err); }); initMongoose();
另外请确认MongoDB Atlas配置:
- 你当前运行代码的公网IP已经加入Atlas的IP白名单
- 连接字符串中的用户名、密码、数据库名配置正确
- 对应用户有对应数据库的读写权限
2. 修正Schema定义的错误
你当前的Schema写法有两个隐患:
general字段直接声明type: Object会导致Mongoose自动变更检测失效default直接传入类实例,会导致所有文档复用同一个实例对象,出现数据串扰的问题
修正后的./models/guild.js代码:
const { model, Schema } = require('mongoose'); const GeneralModuleSchema = new Schema({ prefix: { type: String, default: '/' }, blacklistedChannelIds: { type: [String], default: [] } }); const GuildSchema = new Schema({ _id: String, general: { type: GeneralModuleSchema, default: () => ({}) } }); module.exports = model('guild', GuildSchema);
你之前写的markModified("guild")属于字段名写错,正确的字段名是general,所以该写法完全无效。
3. 给数据操作加错误捕获
你当前的get方法没有异常捕获,操作抛出的错误会变成未处理的Promise拒绝,如果你没有监听unhandledRejection事件就完全看不到报错,修正后的代码:
const SavedGuild = require('./models/guild.js'); module.exports = new class { async get(id) { try { const existed = await SavedGuild.findById(id); if (existed) return existed; const newGuild = new SavedGuild({ _id: id }); return await newGuild.save(); } catch (err) { console.error('get guild error:', err); throw err; } } }
修改完成后重新运行代码,控制台会打印出具体的错误信息,就可以定位具体问题了。
内容的提问来源于stack exchange,提问作者SirGolem
相关产品推荐
相关产品推荐

