Node.js Discord Bot遇MongoDB重复键错误后崩溃的解决求助
解决Mongoose重复键错误导致Discord机器人崩溃的方案
你的问题核心是未捕获MongoDB的重复键错误,导致Node.js进程因未处理的Promise拒绝而崩溃。以下是具体解决步骤:
1. 修正Schema拼写错误
首先,你的Schema中require是拼写错误,应该改为required,否则字段必填验证不会生效:
mongoose.connect(process.env.MONGO_KEY) const movieSchema = new mongoose.Schema({ title: {type: String, unique: true, required: true}, // 修正require为required link: {type: String, unique: true, sparse: true} }); module.exports = mongoose.model('Movie', movieSchema);
2. 捕获重复键错误并友好提示用户
在电影提交代码中,用try-catch包裹异步保存操作,捕获E11000错误码(MongoDB重复键错误的标识),并向用户回复提示:
if(command.includes('sendreclink!')){ try { const arr = message.content.split('!') console.log(arr[1], arr[2]) const movieTitle = arr[1].trim().split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ') const movie = new Movie({title: movieTitle , link: arr[2]}) await movie.save() message.reply(`${movieTitle} 已添加到推荐列表`) } catch (err) { // 精准捕获重复键错误 if (err.code === 11000) { message.reply(`${movieTitle} 已经存在于数据库中,无需重复提交!`) } else { // 处理其他未知错误 console.error('保存电影数据失败:', err) message.reply('提交失败,请稍后重试') } } }
3. 可选:提前查询避免触发错误(优化体验)
为了减少错误触发的概率,可以在保存前先查询数据库是否已存在该电影,同时保留错误处理应对并发场景(比如两个用户同时提交同一电影的情况):
if(command.includes('sendreclink!')){ try { const arr = message.content.split('!') console.log(arr[1], arr[2]) const movieTitle = arr[1].trim().split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ') // 先查询是否存在该电影 const existingMovie = await Movie.findOne({ title: movieTitle }) if (existingMovie) { return message.reply(`${movieTitle} 已经存在于数据库中,无需重复提交!`) } const movie = new Movie({title: movieTitle , link: arr[2]}) await movie.save() message.reply(`${movieTitle} 已添加到推荐列表`) } catch (err) { console.error('处理电影提交失败:', err) message.reply('提交失败,请稍后重试') } }
关键原理
- MongoDB的
E11000错误码专门用于标识唯一索引冲突,通过捕获这个错误可以精准处理重复提交的场景 try-catch可以捕获异步操作中的错误,避免未处理的Promise拒绝导致Node.js进程崩溃
内容的提问来源于stack exchange,提问作者angelplusultra
相关产品推荐
相关产品推荐

