discord.py
discord.py copied to clipboard
Pass error raised in subcommands to local error handler of its parent group command.
The Problem
If several subcommands of a certain group command raises same error, we will have to add local error handler method to each of these subcommands which makes us repeat same block of codes. Obviously we can add it to our global error handler but its not wise to do so if that error is meaningful only for those particular sets of group commands. It will enable group commands to have its own single error handler method for its several subcommands.
The Ideal Solution
@commands.group()
async def profile(ctx, user=None):
pass
@profile.error
async def profile_error(ctx, error):
if isinstance(error, ProfileNotCreatedError):
await ctx.send("You have not created your profile yet. Use ;profile create command now to create your profile.")
@profile.command()
async def name(ctx):
raise ProfileNotCreatedError
@profile.command()
async def description(ctx):
raise ProfileNotCreatedError
@profile.command()
async def color(ctx):
raise ProfileNotCreatedError
The Current Solution
@commands.group()
async def profile(ctx, user=None):
pass
@profile.command()
async def name(ctx):
raise ProfileNotCreatedError
@name.error
async def name_error(ctx, error):
if isinstance(error, ProfileNotCreatedError):
await ctx.send("You have not created your profile yet. Use ;profile create command now to create your profile.")
@profile.command()
async def description(ctx):
raise ProfileNotCreatedError
@description.error
async def description_error(ctx, error):
if isinstance(error, ProfileNotCreatedError):
await ctx.send("You have not created your profile yet. Use ;profile create command now to create your profile.")
@profile.command()
async def color(ctx):
raise ProfileNotCreatedError
@color.error
async def color_error(ctx, error):
if isinstance(error, ProfileNotCreatedError):
await ctx.send("You have not created your profile yet. Use ;profile create command now to create your profile.")
OR
class MyErrorHandler(commands.Cog):
@Cog.listener()
async def on_command_error(self, ctx, error):
if isinstance(error, ProfileNotCreatedError):
await ctx.send("You have not created your profile yet. Use ;profile create command now to create your profile.")
def setup(bot):
bot.add_cog(MyErrorHandler(bot))
Summary
This feature will enable us to organise commands and their own Exceptions in a cleaner way, separating common global Exceptions from Exception raised from some particular interrelated subcommands of a group command.
You can implement this behavior fairly easily with a command subclass, by calling command.root_parent.on_error inside command.dispatch_error.
See:
https://github.com/Rapptz/discord.py/blob/master/discord/ext/commands/core.py#L312-L333
That said, this behavior feels fairly niche for mainline implementation.