Discord.js机器人!am命令报错:TypeError: Cannot read properties of null (reading 'save')
Discord.js机器人执行
!am命令时出现Cannot read properties of null (reading 'save')错误 问题原因
错误出在channel.save()调用时,channel为null,这是因为channelModel.findOne({channelId: message.channel.id})在数据库中找不到对应频道的记录。通常发生在第一次在目标频道使用该命令时,数据库还未创建该频道的文档。
解决方案
有两种可行的修复方式,根据你的需求选择:
方案1:使用findOneAndUpdate自动创建文档(推荐)
利用MongoDB的findOneAndUpdate方法,结合upsert: true选项,实现"找不到就创建,找到就更新"的逻辑,同时用$addToSet自动避免重复添加用户ID:
const channelModel = require("../models/channel.model"); module.exports = { name: "am", usage: "@<user> @<optional_user> ...", guildOnly: true, description: "Adds a new member to the standup", async execute(message, args) { if (!args.length) return message.channel.send( "Ruh Roh! You need to mention **_at least_** one member as argument!" ); // 提取所有有效用户ID const memberIds = []; args.forEach((mention) => { if (mention.startsWith("<@") && mention.endsWith(">")) { let userId = mention.slice(2, -1); if (userId.startsWith("!")) userId = userId.slice(1); const member = message.guild.members.cache.get(userId); if (member) memberIds.push(member.id); } }); if (memberIds.length === 0) { return message.channel.send("No valid members mentioned!"); } try { // 查找或创建频道文档,并添加用户ID(自动去重) await channelModel.findOneAndUpdate( { channelId: message.channel.id }, { serverId: message.guild.id, $addToSet: { members: { $each: memberIds } } }, { upsert: true, new: true } ); message.channel.send("Members updated :tada:"); } catch (err) { console.error(err); message.channel.send( "Oh no :scream:! An error occured somewhere in the matrix!" ); } }, };
方案2:手动判断并创建新文档
先检查查询结果是否为null,如果是则手动创建新的Channel实例,再进行后续操作:
const channelModel = require("../models/channel.model"); module.exports = { name: "am", usage: "@<user> @<optional_user> ...", guildOnly: true, description: "Adds a new member to the standup", async execute(message, args) { if (!args.length) return message.channel.send( "Ruh Roh! You need to mention **_at least_** one member as argument!" ); // 查找频道文档 let channel = await channelModel.findOne({ channelId: message.channel.id }); // 如果不存在,创建新文档 if (!channel) { channel = new channelModel({ serverId: message.guild.id, channelId: message.channel.id, members: [] }); } // 处理用户提及 args.forEach((mention) => { if (mention.startsWith("<@") && mention.endsWith(">")) { let userId = mention.slice(2, -1); if (userId.startsWith("!")) userId = userId.slice(1); const member = message.guild.members.cache.get(userId); if (member && channel.members.indexOf(member.id) === -1) { channel.members.push(member.id); } } }); try { await channel.save(); message.channel.send("Members updated :tada:"); } catch (err) { console.error(err); // 修正原代码中的console.err拼写错误 message.channel.send( "Oh no :scream:! An error occured somewhere in the matrix!" ); } }, };
额外注意点
- 原代码中存在拼写错误:
console.err应该改为console.error,已在方案2中修正。 - 使用
async/await替代嵌套的.then()语法,让代码结构更清晰易读。
内容的提问来源于stack exchange,提问作者hannahSugahp
相关产品推荐
相关产品推荐

