Discord机器人婚姻系统报错:无法读取undefined的cache属性
问题
我正在为Discord机器人开发婚姻系统,但无法判断目标用户是否已拥有“Married”角色。以下是我的代码:
const Discord = require('discord.js'); module.exports = { name: "marry", aliases: ['m'], description: "marry someone", async run(client, message, args) { const user = message.mentions.users.first() || client.users.get(args[0]); let marriedRole = message.guild.roles.cache.find(r => r.name === "Married"); let singleRole = message.guild.roles.cache.find(r => r.name === "Single"); let proposerID = message.author.id; let proposerName = message.author.username; if (user.roles.cache.some(marriedRole)) { let embed = new Discord.MessageEmbed() .setDescription(`Sorry **${user.tag}**, is already married!`); let messageEmbed = await message.channel.send({ embeds: [embed] }); } if (message.member.roles.cache.some(role => role.name === 'Single')) { let embed = new Discord.MessageEmbed() .setDescription(`**${user.username}**, **${message.author.username}** is asking for your hand in marriage, would you like to accept?`); let messageEmbed = await message.channel.send({ embeds: [embed] }); messageEmbed.react('✅'); messageEmbed.react('❌'); } if (message.member.roles.cache.some(role => role.name === 'Married')) { let embed = new Discord.MessageEmbed() .setDescription(`Sorry **${message.author.username}**, but you are already married!`); let messageEmbed = await message.channel.send({ embeds: [embed] }); } } }
运行时持续出现以下错误:
if (user.roles.cache.some(marriedRole)) {
^
TypeError: Cannot read properties of undefined (reading 'cache')
解决方案
问题根源
user对象无roles属性:你获取的user是Discord全局用户对象(User类),仅包含用户的全局信息;而角色是服务器内的属性,只有服务器成员对象(GuildMember)才拥有roles属性。- 未处理
user为空的情况:如果用户未提及任何人或输入ID无效,user会是undefined,访问user.roles直接触发报错。 roles.cache.some()用法错误:该方法需要传入回调函数,直接传入角色对象无法生效。
修复步骤
- 获取服务器成员对象:替换全局用户获取方式,直接获取服务器成员(GuildMember),比如用
message.mentions.members.first()或message.guild.members.fetch()。 - 增加参数校验:先判断是否成功获取目标成员,若未获取到则提示用户。
- 修正角色判断逻辑:用
roles.cache.has(role.id)直接判断角色存在性,比some()更高效且避免重名问题。
修改后的完整代码
const Discord = require('discord.js'); module.exports = { name: "marry", aliases: ['m'], description: "marry someone", async run(client, message, args) { // 获取目标服务器成员:优先提及,再尝试ID查找 const targetMember = message.mentions.members.first() || await message.guild.members.fetch(args[0]).catch(() => null); const marriedRole = message.guild.roles.cache.find(r => r.name === "Married"); const singleRole = message.guild.roles.cache.find(r => r.name === "Single"); // 校验目标成员是否有效 if (!targetMember) { const embed = new Discord.MessageEmbed() .setDescription("请提及一个有效的服务器成员或输入正确的用户ID!"); return message.channel.send({ embeds: [embed] }); } // 检查目标是否已婚 if (targetMember.roles.cache.has(marriedRole.id)) { const embed = new Discord.MessageEmbed() .setDescription(`抱歉,**${targetMember.user.tag}** 已经结婚了!`); return message.channel.send({ embeds: [embed] }); } // 检查发起者是否已婚 if (message.member.roles.cache.has(marriedRole.id)) { const embed = new Discord.MessageEmbed() .setDescription(`抱歉,**${message.author.username}**,你已经结婚了!`); return message.channel.send({ embeds: [embed] }); } // 发起者为单身,发送求婚消息 if (message.member.roles.cache.has(singleRole.id)) { const embed = new Discord.MessageEmbed() .setDescription(`**${targetMember.user.username}**,**${message.author.username}** 向你求婚了,你愿意接受吗?`); const messageEmbed = await message.channel.send({ embeds: [embed] }); messageEmbed.react('✅'); messageEmbed.react('❌'); } } }
额外说明
- 使用角色ID判断存在性,避免因角色重名导致的判断错误,同时查询效率更高。
- 每个条件分支后添加
return,触发条件后终止后续代码执行,防止多个提示同时发送。 - 用
catch(() => null)处理ID查找失败的情况,确保targetMember为空时能被正确校验。
内容的提问来源于stack exchange,提问作者John Hayes
相关产品推荐
相关产品推荐

