discord.py框架warn命令无报错不运行且机器人一分钟后离线问题排查
问题修复方案
核心错误点
- 异步函数调用缺失await:
addcaseidtodb中调用异步方法openuseless()时未加await,导致获取到的是协程对象而非字典数据,执行字典操作直接触发异常,是机器人崩溃无输出的核心原因 - ID生成逻辑错误:现有
id_generator仅校验第一个ID是否重复就直接返回,未全量校验已存在ID,且生成的新ID未写入caseids.json,后续会出现ID重复问题 - 类型不匹配:
warn函数中读取警告记录时,将字符串类型的存储ID与整数类型的member.id直接比较,判断永远为False,无法正确获取Case ID - 日志逻辑错误:警告操作的日志模板误用了踢人相关的标题和描述
- 历史记录丢失:
createinfraction中直接覆盖用户的警告记录,会清空该用户之前的所有警告数据 - 空文件兼容缺失:初始状态下如果两个JSON文件为空或不存在,
json.load会直接抛出异常
修复后代码
# 新增空文件兼容处理 async def openinf(): try: with open("infractions.json", "r") as f: users = json.load(f) except (FileNotFoundError, json.JSONDecodeError): users = {} return users async def openuseless(): try: with open("caseids.json", "r") as f: caseids = json.load(f) except (FileNotFoundError, json.JSONDecodeError): caseids = {} return caseids # 补全await关键字 async def addcaseidtodb(caseid): e = await openuseless() e[str(caseid)] = {} with open("caseids.json", "w") as f: json.dump(e, f) return True # 修复ID生成逻辑,全量校验重复 async def id_generator(size=12, chars=string.ascii_uppercase + string.digits): existing = await openuseless() while True: x = ''.join(random.choice(chars) for _ in range(size)) if x not in existing: return x # 修复历史记录覆盖问题,改用列表存储多条警告 async def createinfraction(user, type, mod, date): users = await openinf() idgen1 = await id_generator() # 新增ID入库逻辑 await addcaseidtodb(idgen1) user_id = str(user.id) # 用户无记录则初始化列表 if user_id not in users: users[user_id] = [] # 追加新警告记录 users[user_id].append({ "type": type, "mod": mod.id, "date": date, "caseid": idgen1 }) with open("infractions.json", "w") as f: json.dump(users, f) return idgen1 @client.event async def on_ready(): print("online") @client.command(aliases = ["w"]) async def warn(ctx, member : discord.Member = None, *, reason = None): if member is None: embed = discord.Embed(title = "ERROR", description = "Please specify a valid member.") await ctx.send(ctx.author.mention, embed = embed) elif reason is None: embed = discord.Embed(title = "ERROR", description = "Please specify a reason.") await ctx.send(ctx.author.mention, embed = embed) else: yui = now.strftime("%d/%m/%Y %H:%M:%S") # 直接获取生成的Case ID,无需后续遍历查询 case_id = await createinfraction(member, "Warning", ctx.author, yui) embed = discord.Embed(description= f"You have been warned in {ctx.guild} for {reason}.") await member.send(embed = embed) e = client.get_channel(loggingchannel) # 修复日志标题和描述 embed1 = discord.Embed(title = "Member Warned", description = f"{member} has been warned") embed1.add_field(name = "Reason", value = reason) embed1.add_field(name = "Moderator", value = ctx.author) embed1.add_field(name = "Case ID", value = case_id) embed1.add_field(name = "Date", value = yui) await e.send(embed=embed1)
内容的提问来源于stack exchange,提问作者boredscripter
相关产品推荐
相关产品推荐

