Let's say I have a basic on_command_error event that acts as a global error handler:
@client.event
async def on_command_error(ctx, error):
if isinstance(error, BadArgument):
await ctx.reply("That input was wrong!")
return
elif isinstance(error, NotFound):
await ctx.reply("I couldn't find that member!")
return
raise error
And I also have a command with a local error handler, like this:
@client.command()
async def number(ctx, amount):
if not amount.isnumeric():
raise BadArgument
ctx.guild.get_member(1) #creating a NotFound error
@number.error
async def number_error(ctx, error):
if isinstance(error, BadArgument):
await ctx.reply("This is a special answer!")
Is it possible to make it so that, if the local error handler doesn't catch any error, then it calls the global error handler?
In this case, the ideal scenario would be: if the command raises BadArgument, then it should reply with "This is a special answer!" from the local error handler, and that's it.
But if it raises NotFound, then it should reply "I couldn't find that member!", from the global error handler.
Generic handlers are always called by discord.py after local handlers.
In your case, it works as intended. number_error
is called first, and then your global on_command_error
is called.
You can set a flag to ignore it, like this:
@raise_exception.error
async def raise_exception_error(ctx, err):
if isinstance(err, commands.CommandInvokeError) and isinstance(err.__cause__, RuntimeError):
await ctx.send('ignoring!')
ctx._ignore_me_ = True
return
await ctx.send(f'propagating this error to `on_command_error`: `{err.__class__.__name__}: {err}`')
@client.event
async def on_command_error(ctx, err):
if hasattr(ctx, '_ignore_me_'):
await ctx.send('skipped!')
return
await ctx.send(f'caught in `on_command_error`: `{err.__class__.__name__}` -> `{err}`')
That outputs:
In your case, you can use it like this:
@number.error
async def number_error(ctx, error):
if isinstance(error, BadArgument):
await ctx.reply("This is a special answer!")
ctx._ignore_me_ = True
@client.event
async def on_command_error(ctx, error):
if hasattr(ctx, '_ignore_me_'):
return