使用mongoose调用findOne报Cannot read property 'findOne' of undefined如何解决
报错直接原因
你遇到的TypeError: Cannot read property 'findOne' of undefined错误核心是Guild模型的导入导出规则不匹配:
- Guild模型文件中使用的是默认导出语法:
module.exports = mongoose.model('Guild', guildSchema) - 业务代码中使用了解构导入语法:
const { Guild } = require('../../models/Guild'),该语法只能获取命名导出的内容,因此你获取到的Guild变量实际是undefined,调用其findOne方法自然触发报错。
修复方法
直接修改业务代码的导入语句即可:
// 原错误写法 // const { Guild } = require('../../models/Guild'); // 修正为默认导入 const Guild = require('../../models/Guild');
其他潜在代码问题
修复导入问题后还需要处理以下逻辑缺陷,避免后续出现其他报错:
- 无查询结果/错误处理逻辑:现有回调写法中没有判断
err是否存在、也没有判断doc是否为空,若数据库查询出错、或对应guildID无匹配记录,直接访问doc.prefix会再次触发undefined属性读取错误 - 变量未初始化就使用:代码中声明了
let prefixConfig但未赋值,最后返回成功消息时${prefixConfig}会输出undefined - 异步操作无等待:
doc.save()是异步方法,现有写法不等保存完成就返回成功消息,可能出现数据库写入失败但用户收到成功提示的逻辑不一致问题 - 参数校验时机晚:参数合法性校验放在数据库查询之后,会造成不必要的数据库查询开销
优化后完整代码参考
const Guild = require('../../models/Guild'); async function prefixCommand (msg, args) { // 权限校验 if (!msg.member.permissions.has('manageGuild') && !this.config.options.devs.includes(msg.author.id)) { return msg.channel.createMessage('You need `manageGuild` to be able to use this command!'); } // 提前做参数校验 if (!args[0]) { return msg.channel.createMessage('Prefix is a required argument!\nUsage: `prefix <prefix>`'); } const newPrefix = args.join(' ').toLowerCase(); if (newPrefix.length > 32) { return msg.channel.createMessage(`Your prefix cannot be over 30 characters long! You are ${newPrefix.length - 32} characters over the limit.`); } try { // 使用findOneAndUpdate一次完成查询+更新,不存在对应记录时自动新建 const updatedGuild = await Guild.findOneAndUpdate( { guildID: msg.channel.guild.id }, { $set: { prefix: newPrefix } }, { new: true, upsert: true } ); // 判断是否和原有前缀重复 if (updatedGuild.prefix === newPrefix) { return msg.channel.createMessage(`\`${newPrefix}\` is already your current prefix.`); } return msg.channel.createMessage(`Prefix has been set to \`${newPrefix}\``); } catch (error) { // 可按需添加错误日志打印逻辑 return msg.channel.createMessage('Failed to update prefix, please try again later.'); } }
内容的提问来源于stack exchange,提问作者ETLegacy
相关产品推荐
相关产品推荐

