Discord.js运行触发Uncaught TypeError无法读取roles属性问题求助
报错原因
- 属性访问路径错误:discord.js v13及以上版本中,服务器角色缓存的正确访问路径为
message.guild.roles.cache,你代码中写反层级为message.guild.cache.roles,message.guild下不存在cache属性,读取该属性下的roles自然触发undefined报错。 - 未兼容私信场景:当用户给机器人发送私信触发
messageCreate事件时,message.guild的值为null,直接访问其下属属性也会触发该报错。 - 原有校验逻辑不符合需求:你当前的代码逻辑是校验「当前服务器是否存在指定ID的角色」,而非你需要实现的「触发命令的用户是否持有该白名单角色」,逻辑完全错位,即使解决报错也达不到权限校验的效果。
修复方案
- 先过滤无效触发场景:在事件回调最开头判断如果是私信消息、或者是机器人自身发送的消息,直接终止执行。
- 修正权限校验逻辑:从触发用户的身份成员对象
message.member中读取持有角色列表,直接用has方法按ID查询是否持有白名单角色,性能比find更高。 - 修复后的完整
messageCreate事件代码如下:
bot.on("messageCreate", message => { // 过滤私信、机器人自身发送的消息 if (!message.guild || message.author.bot) return; if(message.content === prefix + "help") { // 校验用户是否持有白名单角色 if (!message.member.roles.cache.has('873595824469344256')) return; // 原有帮助Embed逻辑不变 let helpembed = new Discord.MessageEmbed() .setColor('#0099ff') .setTitle('Help Guide') .setAuthor('Request : ' + `${message.author.username}`) .addFields( { name: 'Ban Usage', value: `${prefix}ban **id** | **reason** | **time** \n**__Exemple__** : ${prefix}ban id ALT-F4+Troll (without espace) 32H`}, { name: 'Warn Usage', value: `${prefix}warn **id** | **reason** | **time** \n**__Exemple__** : ${prefix}warn id Bunny-Hope (without espace) warn-1/2/3`}, ) .setFooter('© ©'); message.reply({ embeds: [helpembed] }); }; });
内容的提问来源于stack exchange,提问作者HaKerZa
相关产品推荐
相关产品推荐

