Discord.py使用await调用channel.edit时异常捕获失效问题
问题根因
你的异常捕获失效是三个代码逻辑错误共同导致的:
- 现有
try块的捕获范围仅覆盖了requests.head(url)这一行,所有channel.edit()调用(无论在except分支还是else分支)都不在异常捕获范围内。给channel.edit()加上await后,这个异步调用抛出的异常(比如权限不足、接口限频、频道不存在)不会被当前的except逻辑捕获,会直接抛到事件循环导致检测任务崩溃。 - 你使用的同步
requests库会阻塞整个Discord bot的异步事件循环,会导致bot所有其他功能(响应命令、接收消息、处理心跳)全部卡住,异步代码中不能直接运行同步阻塞的网络请求。 await asyncio.sleep(0)写在了while True循环的外部,循环启动后会无限空跑占满CPU,根本不会执行到sleep语句;且0秒间隔完全没有实际意义,频繁调用频道编辑接口还会触发Discord的API速率限制。
修复方案
按以下步骤修改代码即可:
- 将同步
requests库替换为异步HTTP库aiohttp,避免阻塞事件循环,先执行安装命令:pip install aiohttp - 调整
try块范围,把所有网络请求、频道编辑操作都纳入异常捕获,避免单步出错直接终止整个检测任务 - 将
asyncio.sleep移到while循环内部,设置合理的轮询间隔(建议不短于60秒,符合Discord API的频率限制要求) - 所有
channel.edit()调用前都加上await,确保协程实际执行
修正后的完整代码如下:
import asyncio import aiohttp async def timer(): await bot.wait_until_ready() channel = bot.get_channel(123456) # 替换为你的实际频道ID check_interval = 60 # 检测间隔,单位:秒,可按需调整,不建议低于60 async with aiohttp.ClientSession() as session: while True: try: async with session.head(url) as response: if response.status == 200: print("OK") await channel.edit(name="website-is-up") else: print(f"NOT OK: HTTP response code {response.status}") await channel.edit(name="website-is-down") except Exception as e: print(f"NOT OK: {str(e)}") # 频道编辑操作单独加异常捕获,避免编辑本身出错终止任务 try: await channel.edit(name="website-is-down") except Exception as edit_err: print(f"Failed to update channel name: {str(edit_err)}") # 每次检测完成后等待指定间隔再执行下一次检测 await asyncio.sleep(check_interval) bot.loop.create_task(timer())
注意:Discord对频道名称修改有严格的频率限制,短时间内多次修改会触发接口限流导致编辑失败,不要把检测间隔设置得过短。
内容的提问来源于stack exchange,提问作者Destiny Wotsit
相关产品推荐
相关产品推荐

