如何避免用户离开服务器后Discord.js角色操作触发报错?
解决方案
问题根源
用户离开服务器时,guildMemberRemove事件中移除其表情反应会触发messageReactionRemove,但此时用户已不在服务器内,尝试获取该成员并移除角色时会因找不到成员而报错。
方案一:在messageReactionRemove中验证成员存在性并捕获错误
修改messageReactionRemove事件逻辑,先尝试获取成员,若成员不存在(已离开)则跳过角色移除操作,同时捕获API错误避免报错:
client.on('messageReactionRemove', async (reaction, user) => { // 只处理目标消息的反应移除 if (reaction.message.id !== '1110918756189884496') return; const guild = reaction.message.guild; // 获取目标角色 const role = guild.roles.cache.find(role => role.name === "Verified"); if (!role) return; try { // 优先从缓存取成员,缓存无则调用API获取 const member = guild.members.cache.get(user.id) || await guild.members.fetch(user.id); // 移除角色 await member.roles.remove(role); } catch (error) { // 捕获"Unknown member"错误(错误码10007),说明用户已离开,无需处理 if (error.code === 10007) return; // 其他错误输出日志 console.error('移除角色失败:', error); } });
方案二:直接检查缓存中的成员存在性
如果不需要处理缓存未同步的极端情况,也可以直接检查缓存中是否存在该成员,不存在则跳过:
client.on('messageReactionRemove', (reaction, user) => { if (reaction.message.id !== '1110918756189884496') return; const guild = reaction.message.guild; const role = guild.roles.cache.find(role => role.name === "Verified"); if (!role) return; // 检查用户是否仍在服务器缓存中 const member = guild.members.cache.get(user.id); if (member) { member.roles.remove(role); } });
额外优化建议
- 避免硬编码ID和角色名称,可将这些配置项抽离到单独的配置文件,方便维护。
- 在
guildMemberRemove事件中添加错误捕获,避免因消息或反应不存在导致的报错:
client.on("guildMemberRemove", async (member) => { try { const channel = member.guild.channels.cache.get('1109131318350053457'); if (!channel) return; const message = await channel.messages.fetch('1110918756189884496'); const reaction = message.reactions.cache.find(r => r.emoji.name === "✅"); if (reaction) { await reaction.users.remove(member.user.id); } } catch (error) { console.error('移除用户反应失败:', error); } });
内容的提问来源于stack exchange,提问作者Cutefier
相关产品推荐
相关产品推荐

