为什么 on_command_error 在我已经忽略一条错误命令的消息时触发?

Why does on_command_error fire when I have already ignored a message that is a bad command?

我的机器人的唯一 cog 中有以下 2 个侦听器:

@Cog.listener()
async def on_command_error(self, ctx, error)  :
    if isinstance(error, CommandNotFound):
        await ctx.send_help()

@Cog.listener()
async def on_message(self, message):
    if message.author.bot:
        return
    if message.content.startswith(">--"):
        return

命令前缀是 >-,我的印象是 return>-- 开头的消息意味着消息不超过 on_message,但是当我给出命令 >--halp 时,on_command_error 触发并显示错误:

CommandNotFound('Command "-halp" is not found')

我对如何忽略消息的理解有误吗,或者 on_command_error 甚至会为“死”消息触发,或者我做错了什么?

在 cog 中注册监听器不会替换机器人使用的默认监听器(如果存在默认监听器)。

在您的情况下,每次将消息发送到机器人可以看到的频道时,齿轮中的自定义 on_message 事件以及默认 on_message 事件都会触发。

这就是引发 CommandNotFound 错误的原因,因为默认 on_message 事件仍会尝试处理消息并检查是否调用了命令。

如果您覆盖主文件(定义机器人客户端的地方)中的默认 on_message 事件,那么两个自定义 on_message 事件仍将触发(主要和齿轮)。

这可以通过以下方式验证。当机器人看到一条消息时,bot.pycog.py 都会被打印出来,表示 on_message 事件都被触发了。

bot.py

from discord.ext import commands

client = commands.Bot(command_prefix='>-')

client.load_extension('cog')

@client.event
async def on_message(message):
    print('bot.py')
    await client.process_commands(message)

client.run('TOKEN')

cog.py

from discord.ext import commands

class TestCog(commands.Cog):
    
    def __init__(self, bot):
        self.bot = bot

    @commands.Cog.listener()
    async def on_message(self, message):
        print('cog.py')

def setup(bot):
    bot.add_cog(TestCog(bot))

如果您希望机器人完全忽略某些消息,则需要在定义机器人客户端的文件中的自定义 on_message 事件中执行此操作。