From b53d8d8b7fe7c33c6931fa9075c30c27ea9c02da Mon Sep 17 00:00:00 2001 From: sco1 Date: Sun, 3 Mar 2019 21:50:01 -0500 Subject: Add new Cog class inheritance & event listener decoration Mitigates recent breaking d.py changes --- bot/bot.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'bot/bot.py') diff --git a/bot/bot.py b/bot/bot.py index 12291a5f..84bac598 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -6,7 +6,7 @@ from typing import List from aiohttp import AsyncResolver, ClientSession, TCPConnector from discord import Embed from discord.ext import commands -from discord.ext.commands import Bot +from discord.ext.commands import Bot, Cog from bot import constants @@ -63,6 +63,7 @@ class SeasonalBot(Bot): await devlog.send(embed=embed) + @Cog.listener() async def on_command_error(self, context, exception): # Don't punish the user for getting the arguments wrong if isinstance(exception, commands.UserInputError): -- cgit v1.2.3 From 79b16232c62c6381c1669718a718bba6acddc958 Mon Sep 17 00:00:00 2001 From: Scragly <29337040+scragly@users.noreply.github.com> Date: Tue, 26 Mar 2019 13:53:54 +1000 Subject: Recombine error handlers into the main listener. Fix cooldown revert. --- bot/bot.py | 17 ++---- bot/seasons/evergreen/error_handler.py | 99 ++++++++++++++++------------------ 2 files changed, 48 insertions(+), 68 deletions(-) (limited to 'bot/bot.py') diff --git a/bot/bot.py b/bot/bot.py index c1198957..d60390c3 100644 --- a/bot/bot.py +++ b/bot/bot.py @@ -5,8 +5,7 @@ from typing import List from aiohttp import AsyncResolver, ClientSession, TCPConnector from discord import Embed -from discord.ext import commands -from discord.ext.commands import Bot, Cog +from discord.ext.commands import Bot from bot import constants @@ -19,10 +18,7 @@ class SeasonalBot(Bot): def __init__(self, **kwargs): super().__init__(**kwargs) self.http_session = ClientSession( - connector=TCPConnector( - resolver=AsyncResolver(), - family=socket.AF_INET, - ) + connector=TCPConnector(resolver=AsyncResolver(), family=socket.AF_INET) ) def load_extensions(self, exts: List[str]): @@ -49,6 +45,7 @@ class SeasonalBot(Bot): """ Send an embed message to the devlog channel """ + devlog = self.get_channel(constants.Channels.devlog) if not devlog: @@ -62,11 +59,3 @@ class SeasonalBot(Bot): embed.set_author(name=title, icon_url=icon) await devlog.send(embed=embed) - - @Cog.listener() - async def on_command_error(self, context, exception): - # Don't punish the user for getting the arguments wrong - if isinstance(exception, commands.UserInputError): - context.command.reset_cooldown(context) - else: - await super().on_command_error(context, exception) diff --git a/bot/seasons/evergreen/error_handler.py b/bot/seasons/evergreen/error_handler.py index 19c22ed8..c60e33ee 100644 --- a/bot/seasons/evergreen/error_handler.py +++ b/bot/seasons/evergreen/error_handler.py @@ -14,98 +14,89 @@ class CommandErrorHandler(commands.Cog): def __init__(self, bot): self.bot = bot + @staticmethod + def revert_cooldown_counter(command, message): + """Undoes the last cooldown counter for user-error cases.""" + if command._buckets.valid: + bucket = command._buckets.get_bucket(message) + bucket._tokens = min(bucket.rate, bucket._tokens + 1) + logging.debug( + "Cooldown counter reverted as the command was not used correctly." + ) + @commands.Cog.listener() async def on_command_error(self, ctx, error): """Activates when a command opens an error""" if hasattr(ctx.command, 'on_error'): return logging.debug( - "A command error occured but " - "the command had it's own error handler" + "A command error occured but the command had it's own error handler." ) + error = getattr(error, 'original', error) + if isinstance(error, commands.CommandNotFound): return logging.debug( - f"{ctx.author} called '{ctx.message.content}' " - "but no command was found" + f"{ctx.author} called '{ctx.message.content}' but no command was found." ) + if isinstance(error, commands.UserInputError): logging.debug( - f"{ctx.author} called the command '{ctx.command}' " - "but entered invalid input!" + f"{ctx.author} called the command '{ctx.command}' but entered invalid input!" ) + + self.revert_cooldown_counter(ctx.command, ctx.message) + return await ctx.send( - ":no_entry: The command you specified failed to run." + ":no_entry: The command you specified failed to run. " "This is because the arguments you provided were invalid." ) + if isinstance(error, commands.CommandOnCooldown): logging.debug( - f"{ctx.author} called the command '{ctx.command}' " - "but they were on cooldown!" + f"{ctx.author} called the command '{ctx.command}' but they were on cooldown!" ) - seconds = error.retry_after - remaining_minutes, remaining_seconds = divmod(seconds, 60) - time_remaining = f'{int(remaining_minutes)} minutes {math.ceil(remaining_seconds)} seconds' + remaining_minutes, remaining_seconds = divmod(error.retry_after, 60) + return await ctx.send( - "This command is on cooldown," - f" please retry in {time_remaining}." + f"This command is on cooldown, please retry in " + f"{int(remaining_minutes)} minutes {math.ceil(remaining_seconds)} seconds." ) + if isinstance(error, commands.DisabledCommand): logging.debug( - f"{ctx.author} called the command '{ctx.command}' " - "but the command was disabled!" - ) - return await ctx.send( - ":no_entry: This command has been disabled." + f"{ctx.author} called the command '{ctx.command}' but the command was disabled!" ) + return await ctx.send(":no_entry: This command has been disabled.") + if isinstance(error, commands.NoPrivateMessage): logging.debug( f"{ctx.author} called the command '{ctx.command}' " "in a private message however the command was guild only!" ) - return await ctx.author.send( - ":no_entry: This command can only be used inside a server." - ) + return await ctx.author.send(":no_entry: This command can only be used in the server.") + if isinstance(error, commands.BadArgument): - if ctx.command.qualified_name == 'tag list': - logging.debug( - f"{ctx.author} called the command '{ctx.command}' " - "but entered an invalid user!" - ) - return await ctx.send( - "I could not find that member. Please try again." - ) - else: - logging.debug( - f"{ctx.author} called the command '{ctx.command}' " - "but entered a bad argument!" - ) - return await ctx.send( - "The argument you provided was invalid." - ) - if isinstance(error, commands.CheckFailure): + self.revert_cooldown_counter(ctx.command, ctx.message) + logging.debug( - f"{ctx.author} called the command '{ctx.command}' " - "but the checks failed!" - ) - return await ctx.send( - ":no_entry: You are not authorized to use this command." + f"{ctx.author} called the command '{ctx.command}' but entered a bad argument!" ) - print( - f"Ignoring exception in command {ctx.command}:", - file=sys.stderr - ) + return await ctx.send("The argument you provided was invalid.") + + if isinstance(error, commands.CheckFailure): + logging.debug(f"{ctx.author} called the command '{ctx.command}' but the checks failed!") + return await ctx.send(":no_entry: You are not authorized to use this command.") + + print(f"Ignoring exception in command {ctx.command}:", file=sys.stderr) + logging.warning( f"{ctx.author} called the command '{ctx.command}' " "however the command failed to run with the error:" f"-------------\n{error}" ) - traceback.print_exception( - type(error), - error, - error.__traceback__, - file=sys.stderr - ) + + traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr) def setup(bot): -- cgit v1.2.3