Discord.py角色权限命令异常:无权限无提示且命令失效
Discord.py机器人角色权限命令问题修复
问题1:使用@commands.has_role装饰器时,无权限用户触发命令无提示
原代码里的try-except无法捕获装饰器抛出的MissingRole异常——因为装饰器的权限校验在命令函数执行前就完成了,异常根本不会进入函数内部的try块。
修复方案
用@commands.error装饰器专门处理命令异常:
@bot.command() @commands.has_role("Saloon Member") async def caca(ctx): await ctx.send("Hi") @caca.error async def caca_error(ctx, error): if isinstance(error, commands.MissingRole): await ctx.send("小家伙,你没有Saloon Member权限哦")
问题2:自定义check_role校验导致所有命令无响应
原自定义校验函数存在多处逻辑错误:
- 角色名转成小写后,判断时却用了原大小写的"Saloon Member",永远匹配不上
- 逻辑完全颠倒:有角色时返回
False、无角色时返回True,彻底搞反了权限校验逻辑 - 多余的
ctx.message.startswith(bot.command_prefix)判断——命令触发时已经过前缀校验,且写法错误(应为ctx.message.content.startswith) - 无返回值的
return会默认返回None,被视为False导致命令直接终止
修复后的check_role函数及命令示例
async def check_role(ctx): member = ctx.author # 统一转小写判断,避免大小写差异问题 role_names = [r.name.lower() for r in member.roles] # 排除机器人自身调用 if member.bot: return False # 校验是否拥有目标角色(同步转小写) if "saloon member" not in role_names: await ctx.send("哈哈,你没有会员权限,#安息吧") return False return True @bot.command() async def inspirobot(ctx): if not await check_role(ctx): return response = requests.get("http://inspirobot.me/api?generate=true") image_url = response.text await ctx.send(image_url)
补充:赋予角色命令的优化建议
原命令仅给发送者添加角色,可增加权限校验确保只有管理员能执行:
@bot.command() @commands.has_permissions(administrator=True) async def givemembership(ctx, member: discord.Member=None): # 默认给发送者添加,也可指定目标成员 target_member = member or ctx.author role = discord.utils.get(target_member.guild.roles, name="Saloon Member") if role: await target_member.add_roles(role) await ctx.send(f"已给{target_member.display_name}添加Saloon Member角色") else: await ctx.send("Saloon Member角色不存在") @givemembership.error async def givemembership_error(ctx, error): if isinstance(error, commands.MissingPermissions): await ctx.send("你没有执行此命令的权限")
内容的提问来源于stack exchange,提问作者Soren Forgeman
相关产品推荐
相关产品推荐

