机器人代码为何忽略第二个异步函数?问题排查及修正
问题描述
机器人管理users和bans两张数据表,各有一条测试用户条目。预设逻辑为:将新评论者ID写入users表,检查该ID是否在bans表中——若在封禁列表则删除评论,否则检查评论中的违禁词。目前第一个函数可正常添加用户,但程序会直接跳至第三个违禁词检查函数执行,第二个封禁检查函数完全不生效,封禁用户的评论未被处理,代码运行无报错。
原代码如下:
主逻辑代码
@dp.message_handler() # 将ID添加至users表 async def check_database(message: types.Message): if not db.user_exists(message.from_user.id): db.add_user(message.from_user.id, message.from_user.first_name) await check_bans(message) await mess_handler(message) async def check_bans(message: types.Message): # 检查用户ID是否在封禁列表中,删除其评论 if db.user_bans(message.from_user.id): await message.delete() await mess_handler(message) async def mess_handler(message: types.Message): # 若存在违禁词则删除评论 text = message.text.lower() if str(message.from_user.id) != cfg.ADMIN_ID: for word in cfg.WORDS: if word in text: await message.delete()
db.py 文件
class Database: def __init__(self, db_file): self.connection = sqlite3.connect(db_file) self.cursor = self.connection.cursor() def user_exists(self, user_id): with self.connection: result = self.cursor.execute("SELECT * FROM 'users' WHERE 'user_id' = ?", (user_id,)).fetchall() return bool(len(result)) def user_bans(self, user_id): with self.connection: result1 = self.cursor.execute("SELECT * FROM 'bans' WHERE 'user_id' = ?", (user_id,)).fetchall() return bool(len(result1))
错误点分析
- 封禁检查仅针对新用户:原代码中
await check_bans(message)只在if not db.user_exists(...)的分支里执行,意味着只有首次发消息的新用户会触发封禁检查,已存在于users表的封禁用户发消息时,完全不会调用封禁检查逻辑。 - 逻辑冗余且混乱:
check_bans函数在删除封禁用户评论后,仍调用mess_handler执行违禁词检查,属于无效操作,还会导致逻辑流程混乱。 - 消息处理器覆盖问题:只有
check_database带有@dp.message_handler()装饰器,是唯一被注册的消息处理器。老用户的消息触发该函数时,会直接跳过封禁检查分支,直接进入后续逻辑。
修正后的代码
主逻辑代码
@dp.message_handler() async def handle_message(message: types.Message): # 先处理用户入库逻辑 if not db.user_exists(message.from_user.id): db.add_user(message.from_user.id, message.from_user.first_name) # 优先执行封禁检查,若为封禁用户则直接返回,不执行后续逻辑 if await check_bans(message): return # 非封禁用户执行违禁词检查 await mess_handler(message) async def check_bans(message: types.Message): # 检查用户是否在封禁列表,是则删除评论并返回True标记已处理 if db.user_bans(message.from_user.id): await message.delete() return True return False async def mess_handler(message: types.Message): # 管理员用户直接跳过违禁词检查 if str(message.from_user.id) == cfg.ADMIN_ID: return text = message.text.lower() for word in cfg.WORDS: if word in text: await message.delete() break # 找到违禁词后停止循环,避免重复执行删除操作
db.py 文件(无需修改)
import sqlite3 class Database: def __init__(self, db_file): self.connection = sqlite3.connect(db_file) self.cursor = self.connection.cursor() def user_exists(self, user_id): with self.connection: result = self.cursor.execute("SELECT * FROM 'users' WHERE 'user_id' = ?", (user_id,)).fetchall() return bool(len(result)) def user_bans(self, user_id): with self.connection: result1 = self.cursor.execute("SELECT * FROM 'bans' WHERE 'user_id' = ?", (user_id,)).fetchall() return bool(len(result1))
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

