升级discord.js v13后读取guild.id报null属性错误如何解决
问题修复方案
错误原因
- 核心问题是变量命名冲突:你贴的是
banAdd.js的代码,但报错来源于banRemove.js,两个文件都存在相同的逻辑问题:外层事件回调的参数已经有代表Discord服务器对象的guild变量,mongoose的findOne回调里又把返回的数据库文档命名为guild,直接覆盖了外层的服务器对象。当数据库中没有对应服务器的记录时,回调返回的guild为null,此时读取guild.id就会抛出你遇到的类型错误。 - 次要问题是混用了mongoose的
await和回调两种异步写法,逻辑不规范,在discord.js v13要求的更高Node版本环境下容易出现时序异常。 - 额外排查点:discord.js v13强制要求声明网关意图,
guildBanAdd/guildBanRemove事件需要你在客户端初始化时开启GuildBans意图,否则事件可能触发异常、参数缺失。
修复代码
你可以直接替换为如下规范的纯await写法的代码,banAdd.js和banRemove.js都按这个逻辑修改即可:
const { MessageEmbed} = require("discord.js"); const {red_light} = require("../../other/colors.json"); const Channel = require('../../models/ModerationModel.js'); module.exports = async (bot, guild, user) => { // 纯await写法,避免回调变量覆盖问题 let guildDB = await Channel.findOne({ guildId: guild.id }).catch(err => console.error(err)); // 不存在记录则新建 if (!guildDB) { guildDB = new Channel({ guildId: guild.id, // 这里的guild是外层的服务器对象,永远不会为null modChannel: null, msgChannel: null }); await guildDB.save().catch(err => console.error(err)); } const modChannel = guild.channels.cache.get(guildDB.modChannel); if (!modChannel) { return console.log(`No message channel found`); } let mEmbed = new MessageEmbed() .setAuthor(`Member Unbanned`, user.displayAvatarURL({dynamic : true})) .setColor(red_light) .setDescription(`${user} ${user.tag}`) .setThumbnail(`${user.displayAvatarURL({dynamic : true})}`) .setFooter(`ID: ${user.id}`) .setTimestamp() modChannel.send({embeds:[mEmbed]}); }
额外配置检查
确认你初始化Discord客户端时已经开启了必要的意图,示例如下:
const { Client, Intents } = require('discord.js'); const bot = new Client({ intents: [ Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_BANS, // 必须开启这个才能正常接收ban相关事件 // 其他你需要的意图 ] });
内容的提问来源于stack exchange,提问作者Nicky
相关产品推荐
相关产品推荐

