我有一个主要带有 cogs 和 app_commands 的机器人,我需要一个错误处理程序,并且我对它有 2 个要求:
到目前为止我发现这是可行的:
@app_commands.command(name="test", description="are u mod")
@app_commands.checks.has_permissions(moderate_members=True)
async def test(self, interaction: discord.Interaction):
await interaction.response.send_message("you are a mod!")
@test.error
async def test_error(self, interaction: discord.Interaction, error):
print(f"{interaction.user} tried to use the `test` command")
await interaction.response.send_message("no")
但这里的问题是我必须为我想要添加的每个管理命令创建这样一个
test_error
函数。我希望为我的 app_commands 提供一个全局错误处理程序。每当任何类型的“缺少 mod 权限”检查失败时,都会执行 test_error
的操作。
我发现的另一件事是:
@bot.tree.error
async def on_app_command_error(interaction: discord.Interaction, error: app_commands.AppCommandError):
if isinstance(error, app_commands.CommandOnCooldown):
return await interaction.response.send_message(error, ephemeral = True)
elif isinstance(error, app_commands.BotMissingPermissions):
return await interaction.response.send_message(error, ephemeral = True)
else:
await interaction.response.send_message("An error occurred!", ephemeral = True)
raise error
并且......它满足第一个要求,有点?它总是只是说“发生错误!”,它永远不会以某种方式到达第一种或第二种情况。而且它也没有解决第二个要求,控制台中仍然发送错误文本墙。
如何处理错误并满足上述两个要求?
如果您需要有关我的机器人的更多信息,这是基本结构:
主.py
bot = commands.Bot(command_prefix='!', intents=discord.Intents.all())
@bot.event
async def on_ready():
print(f'{bot.user} has connected to Discord!')
try:
synced = await bot.tree.sync()
print(f"Synced {len(synced)} command(s)")
except Exception as e:
print(e)
async def load_cogs():
for file in os.listdir('./cogs'):
if file.endswith('.py'):
await bot.load_extension(f'cogs.{file[:-3]}')
asyncio.run(load_cogs())
bot.run(os.getenv('bot_key'))
examplecog.py:
class example(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.Cog.listener()
async def on_ready(self):
print(self.__class__.__name__ + " cog loaded")
@app_commands.command(name="test", description="are u mod")
@app_commands.checks.has_permissions(moderate_members=True)
async def test(self, interaction: discord.Interaction):
await interaction.response.send_message("you are a mod!")
async def example(bot):
await bot.add_cog(errors(bot))
经过几个小时的挖掘,我找到了这个解决方案:
async def on_tree_error(interaction: discord.Interaction, error: app_commands.AppCommandError):
if isinstance(error, app_commands.CommandOnCooldown):
return await interaction.response.send_message(f"Command is currently on cooldown! Try again in **{error.retry_after:.2f}** seconds!")
elif isinstance(error, app_commands.MissingPermissions):
return await interaction.response.send_message(f"You're missing permissions to use that")
else:
raise error
bot.tree.on_error = on_tree_error
我将其添加到我的
main.py
文件中,接近末尾。
这就是错误处理应用程序命令所需的全部内容。比我想象的简单,比我想象的好,但也极难找到。几乎在我看到的任何地方,我都看到了我的第一个解决方案,或者“在不和谐的.py 中这是不可能的”。
谁知道也许将来其他人会需要它并且会找到这个。享受吧!
我正在那个平坦的沙漠中行走,名为“显然没有人关心这个问题并做出丑陋的修复”,你的解决方案是我从阴霾中发现的闪烁的旗帜,上面有非常清晰的说明,谢谢