From a1ba380f90e370548608035ed0c32794f95a5a5b Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Sun, 28 Jul 2019 18:58:24 +0200 Subject: Move error handling to more descriptive `ErrorHandler` cog. --- bot/__main__.py | 2 +- bot/cogs/error_handler.py | 78 ++++++++++++++++++++++++++++++++++++++++++++ bot/cogs/events.py | 82 ----------------------------------------------- 3 files changed, 79 insertions(+), 83 deletions(-) create mode 100644 bot/cogs/error_handler.py delete mode 100644 bot/cogs/events.py diff --git a/bot/__main__.py b/bot/__main__.py index 9bfd99098..4bc7d1202 100644 --- a/bot/__main__.py +++ b/bot/__main__.py @@ -31,7 +31,7 @@ bot.http_session = ClientSession( bot.api_client = APIClient(loop=asyncio.get_event_loop()) # Internal/debug -bot.load_extension("bot.cogs.events") +bot.load_extension("bot.cogs.error_handler") bot.load_extension("bot.cogs.filtering") bot.load_extension("bot.cogs.logging") bot.load_extension("bot.cogs.modlog") diff --git a/bot/cogs/error_handler.py b/bot/cogs/error_handler.py new file mode 100644 index 000000000..2db133372 --- /dev/null +++ b/bot/cogs/error_handler.py @@ -0,0 +1,78 @@ +import logging + +from aiohttp import ClientResponseError +from discord.ext.commands import Bot, Context +from discord.ext.commands import ( + BadArgument, + BotMissingPermissions, + CommandError, + CommandInvokeError, + CommandNotFound, + NoPrivateMessage, + UserInputError, +) + + +log = logging.getLogger(__name__) + + +class ErrorHandler: + """Handles errors emttted from commands.""" + + def __init__(self, bot: Bot): + self.bot = bot + + async def on_command_error(self, ctx: Context, e: CommandError): + command = ctx.command + parent = None + + if command is not None: + parent = command.parent + + if parent and command: + help_command = (self.bot.get_command("help"), parent.name, command.name) + elif command: + help_command = (self.bot.get_command("help"), command.name) + else: + help_command = (self.bot.get_command("help"),) + + if hasattr(command, "on_error"): + log.debug(f"Command {command} has a local error handler, ignoring.") + return + + if isinstance(e, CommandNotFound) and not hasattr(ctx, "invoked_from_error_handler"): + tags_get_command = self.bot.get_command("tags get") + ctx.invoked_from_error_handler = True + + # Return to not raise the exception + return await ctx.invoke(tags_get_command, tag_name=ctx.invoked_with) + elif isinstance(e, BadArgument): + await ctx.send(f"Bad argument: {e}\n") + await ctx.invoke(*help_command) + elif isinstance(e, UserInputError): + await ctx.invoke(*help_command) + elif isinstance(e, NoPrivateMessage): + await ctx.send("Sorry, this command can't be used in a private message!") + elif isinstance(e, BotMissingPermissions): + await ctx.send( + f"Sorry, it looks like I don't have the permissions I need to do that.\n\n" + f"Here's what I'm missing: **{e.missing_perms}**" + ) + elif isinstance(e, CommandInvokeError): + if isinstance(e.original, ClientResponseError): + if e.original.code == 404: + await ctx.send("There does not seem to be anything matching your query.") + else: + await ctx.send("BEEP BEEP UNKNOWN API ERROR!=?!??!?!?!?") + + else: + await ctx.send( + f"Sorry, an unexpected error occurred. Please let us know!\n\n```{e}```" + ) + raise e.original + raise e + + +def setup(bot: Bot): + bot.add_cog(ErrorHandler(bot)) + log.info("Cog loaded: Events") diff --git a/bot/cogs/events.py b/bot/cogs/events.py deleted file mode 100644 index d69af365b..000000000 --- a/bot/cogs/events.py +++ /dev/null @@ -1,82 +0,0 @@ -import logging - -from aiohttp import ClientResponseError -from discord import Colour, Embed, Member, Object -from discord.ext.commands import ( - BadArgument, Bot, BotMissingPermissions, - CommandError, CommandInvokeError, CommandNotFound, - Context, NoPrivateMessage, UserInputError -) - -from bot.cogs.modlog import ModLog -from bot.constants import ( - Channels, Colours, DEBUG_MODE, - Guild, Icons, Keys, - Roles, URLs -) -from bot.utils import chunks - -log = logging.getLogger(__name__) - -RESTORE_ROLES = (str(Roles.muted), str(Roles.announcements)) - - -class Events: - """No commands, just event handlers.""" - - def __init__(self, bot: Bot): - self.bot = bot - - async def on_command_error(self, ctx: Context, e: CommandError): - command = ctx.command - parent = None - - if command is not None: - parent = command.parent - - if parent and command: - help_command = (self.bot.get_command("help"), parent.name, command.name) - elif command: - help_command = (self.bot.get_command("help"), command.name) - else: - help_command = (self.bot.get_command("help"),) - - if hasattr(command, "on_error"): - log.debug(f"Command {command} has a local error handler, ignoring.") - return - - if isinstance(e, CommandNotFound) and not hasattr(ctx, "invoked_from_error_handler"): - tags_get_command = self.bot.get_command("tags get") - ctx.invoked_from_error_handler = True - - # Return to not raise the exception - return await ctx.invoke(tags_get_command, tag_name=ctx.invoked_with) - elif isinstance(e, BadArgument): - await ctx.send(f"Bad argument: {e}\n") - await ctx.invoke(*help_command) - elif isinstance(e, UserInputError): - await ctx.invoke(*help_command) - elif isinstance(e, NoPrivateMessage): - await ctx.send("Sorry, this command can't be used in a private message!") - elif isinstance(e, BotMissingPermissions): - await ctx.send( - f"Sorry, it looks like I don't have the permissions I need to do that.\n\n" - f"Here's what I'm missing: **{e.missing_perms}**" - ) - elif isinstance(e, CommandInvokeError): - if isinstance(e.original, ClientResponseError): - if e.original.code == 404: - await ctx.send("There does not seem to be anything matching your query.") - else: - await ctx.send("BEEP BEEP UNKNOWN API ERROR!=?!??!?!?!?") - - else: - await ctx.send( - f"Sorry, an unexpected error occurred. Please let us know!\n\n```{e}```" - ) - raise e.original - raise e - -def setup(bot): - bot.add_cog(Events(bot)) - log.info("Cog loaded: Events") -- cgit v1.2.3