Discord.py 昵称修改命令两处异常问题排查求助
Discord.py 昵称命令问题排查与修复
问题1:修改服务器所有者昵称时判断逻辑未触发
原因
- 逻辑判断错误:代码中写的是
elif member.id == ctx.guild.owner:,ctx.guild.owner返回的是服务器所有者的Member对象,直接和整数类型的用户ID比较永远返回False,所以该判断永远不会触发。 - 判断顺序错误:所有者判断放在了角色层级判断之后,就算修正了判断逻辑,服务器所有者的最高角色通常高于机器人和普通用户,会先触发前面的角色权限判断,轮不到所有者专属提示返回,即使绕过了角色判断,Discord API本身也禁止修改服务器所有者昵称,直接调用接口会直接抛出403权限错误。
修复方案
- 修正判断条件为
member.id == ctx.guild.owner.id - 将所有者判断调整为所有权限判断的第一顺位
问题2:传入无效成员参数时无提示也无报错
原因
MemberNotFound错误处理器仅绑定在了主命令nickname上,Discord.py的子命令(add/remove)触发的参数错误不会被父命令的错误处理器自动捕获,因此错误无法被处理。
修复方案
两种可选方案:
- 给每个子命令单独绑定错误处理器
- 封装统一错误处理逻辑,同时适配主命令和子命令的错误捕获
修复后完整代码
@commands.group(aliases=['nick'], invoke_without_command=True) async def nickname(self, ctx): embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, use the proper format. [-help].", color=discord.Color.orange()) return await ctx.reply(embed=embed, mention_author=False) @nickname.group() async def add(self, ctx, member: discord.Member, *, new_name): # 所有者判断放在最前 if member.id == ctx.guild.owner.id: embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, owners nickname can't be changed.", color=discord.Color.orange()) await ctx.reply(embed=embed, mention_author=False) return if len(new_name) > 32: embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, provide nickname shorter than 32 characters.", color=discord.Color.orange()) return await ctx.reply(embed=embed, mention_author=False) elif member.top_role > ctx.author.top_role: embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, targets role in the hierarchy is higher than yours.", color=discord.Color.orange()) await ctx.reply(embed=embed, mention_author=False) elif ctx.me.top_role <= member.top_role: embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, my role in the hierarchy lesser than targets.", color=discord.Color.orange()) await ctx.reply(embed=embed, mention_author=False) else: try: await member.edit(nick=new_name) embed = discord.Embed(description = "<:ocheckmark:839069223749812264> **Successfully changed {member.name}s nickname to {new_name}** ", color = discord.Colour.orange()) await ctx.reply(embed=embed, mention_author=False) except Exception as e: print(e) @nickname.group(aliases=['rem']) async def remove(self, ctx, member: discord.Member): # 所有者判断放在最前 if member.id == ctx.guild.owner.id: embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, owners nickname can't be changed.", color=discord.Color.orange()) await ctx.reply(embed=embed, mention_author=False) return if member.top_role > ctx.author.top_role: embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, targets role in the hierarchy is higher than yours.", color=discord.Color.orange()) await ctx.reply(embed=embed, mention_author=False) elif ctx.me.top_role <= member.top_role: embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, my role in the hierarchy lesser than targets.", color=discord.Color.orange()) await ctx.reply(embed=embed, mention_author=False) else: try: name = member.name await member.edit(nick=name) embed = discord.Embed(description = "<:ocheckmark:839069223749812264> **Successfully removed {member.name}s nickname** ", color = discord.Colour.orange()) await ctx.reply(embed=embed, mention_author=False) except Exception as e: print(e) # 统一错误处理逻辑 async def handle_nick_error(self, ctx, error): if isinstance(error, commands.MemberNotFound): embed = discord.Embed(description="<:oxmark:839069221207670804> Unsuccessful, I can't find that user in this guild.", color=discord.Color.orange()) await ctx.reply(embed=embed, mention_author=False) # 其他错误可在此补充处理逻辑 else: print(error) # 给所有相关命令绑定错误处理器 @add.error async def add_error(self, ctx, error): await self.handle_nick_error(ctx, error) @remove.error async def remove_error(self, ctx, error): await self.handle_nick_error(ctx, error) @nickname.error async def nickname_error(self, ctx, error): await self.handle_nick_error(ctx, error)
内容的提问来源于stack exchange,提问作者Rohan
相关产品推荐
相关产品推荐

