discord.py 角色白名单检查后没有响应,应该如何排查?
角色 ID 列表缺少逗号,需要先修正。如果贴出的缩进与实际文件一致,缩进也需要调整。这两类语法问题都会阻止相关代码正常加载,无法单独解释“已经打印 admin,随后没有响应”的现象,还需要结合实际运行的代码继续排查。
先修正角色 ID 列表
admin 中从第二个 ID 开始缺少分隔逗号。多个整数直接连续排列会产生 SyntaxError,不会自动组成有效列表。
将 utils/variables.py 改为:
admin = [
1408442799925235794,
1445017368123277460,
1079504634772738078,
1272691594591473695,
1379137477192843264,
]
如果执行命令时确实能打印 admin,说明当前执行的代码与贴出的内容存在差异,或者运行进程仍在使用修改前已加载的内容。保存修改后,重启机器人进程,确保重新导入配置。
白名单不匹配时,也应该执行 else
这段代码检查命令调用者是否至少拥有一个 ID 在 admin 中的角色:
any(r.id in admin for r in ctx.author.roles)
这里检查的是 ctx.author,即执行命令的人。参数 member 是角色登记的目标成员,不参与当前权限判断。
如果没有匹配的角色,结果为 False,程序应执行 else 并发送拒绝消息。“没有收到消息”不能证明程序没有进行检查,也可能是在获取角色、写入数据库或发送消息时发生了异常。
修正缩进,并添加执行位置日志
贴出的代码没有保留类、方法和条件分支所需的缩进。如果实际文件也是这样,Python 无法正常加载。可以按下面的结构整理,再通过日志确认执行停在哪一步:
import discord
from discord.ext import commands
from utils.databases import roles_db
from utils.variables import admin
class Roles(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_group()
async def custom(self, ctx: commands.Context):
return
@custom.command(
name="register",
description="Registers a custom role to a user",
)
async def register(
self,
ctx: commands.Context,
role: discord.Role,
member: discord.Member,
):
print("admin:", admin)
if ctx.guild is None:
await ctx.send("Please use this command in a server.")
return
author_role_ids = [r.id for r in ctx.author.roles]
print("author role IDs:", author_role_ids)
allowed = any(role_id in admin for role_id in author_role_ids)
print("allowed:", allowed)
if not allowed:
print("sending permission denial")
await ctx.send(":x: You do not have the required role.")
print("permission denial sent")
return
print("before insert_one")
roles_db.insert_one({"user_id": member.id, "role_id": role.id})
print("after insert_one")
await ctx.send(":white_check_mark: Role registered!")
print("success message sent")
async def setup(bot):
await bot.add_cog(Roles(bot))
示例保留了原代码中同步调用 insert_one 的方式。由于没有提供 roles_db 的初始化代码,无法判断数据库客户端是同步还是异步。如果实际使用的是异步客户端,应根据其接口要求使用 await。同步数据库调用也可能在等待数据库响应时阻塞当前执行。
根据最后一条日志继续排查
- 只有
admin:查看紧随其后的异常堆栈,确认执行是否在服务器上下文中,以及角色属性访问是否失败。 - 输出
allowed: False:比较调用者角色 ID 与白名单,确认白名单填写的是角色 ID,且类型与r.id一致。这里的r.id是整数。 - 输出
before insert_one,没有after insert_one:检查数据库调用是否报错或仍在等待返回。 - 输出
after insert_one,没有success message sent:检查ctx.send的异常,以及机器人是否有在当前频道发送消息所需的权限。 - 输出
sending permission denial,没有permission denial sent:检查消息发送环节。
同时查看运行终端和已有的命令错误处理器。如果错误处理器吞掉了异常,应让它记录完整堆栈。找到停止位置和实际异常后,再决定修改哪一部分;仅凭没有回复,无法确定是白名单判断出了问题。
备注:内容仅供参考。
