aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar shtlrs <[email protected]>2024-02-18 21:15:26 +0100
committerGravatar shtlrs <[email protected]>2024-03-21 14:29:02 +0100
commitaad7301c270018341a979e409e952dd597c98e3c (patch)
tree1809e36655163f64f7f420aa6051b37ad2578edc
parentimplement the MovedCommandErrorHandler (diff)
implement the handler for the UserInputError exception
-rw-r--r--bot/command_error_handlers/__init__.py2
-rw-r--r--bot/command_error_handlers/_utils.py25
-rw-r--r--bot/command_error_handlers/user_input_error.py32
-rw-r--r--bot/exts/core/error_handler.py9
4 files changed, 58 insertions, 10 deletions
diff --git a/bot/command_error_handlers/__init__.py b/bot/command_error_handlers/__init__.py
index 32c713bd..16d53373 100644
--- a/bot/command_error_handlers/__init__.py
+++ b/bot/command_error_handlers/__init__.py
@@ -5,6 +5,7 @@ from bot.bot import Bot
from .command_not_found import CommandNotFoundErrorHandler
from .default import DefaultCommandErrorHandler
from .moved_command import MovedCommandErrorHandler
+from .user_input_error import UserInputErrorHandler
def bootstrap_command_error_manager(bot: Bot) -> CommandErrorManager:
@@ -13,4 +14,5 @@ def bootstrap_command_error_manager(bot: Bot) -> CommandErrorManager:
manager = CommandErrorManager(default=default_handler)
manager.register_handler(CommandNotFoundErrorHandler(bot))
manager.register_handler(MovedCommandErrorHandler())
+ manager.register_handler(UserInputErrorHandler())
return manager
diff --git a/bot/command_error_handlers/_utils.py b/bot/command_error_handlers/_utils.py
index 3a51bfee..410a8b9d 100644
--- a/bot/command_error_handlers/_utils.py
+++ b/bot/command_error_handlers/_utils.py
@@ -1,10 +1,14 @@
import random
from collections.abc import Iterable
-from discord import Embed
+from discord import Embed, Message
+from discord.ext import commands
+from pydis_core.utils.logging import get_logger
from bot.constants import Colours, ERROR_REPLIES
+log = get_logger(__name__)
+
def create_error_embed(message: str, title: Iterable | str = ERROR_REPLIES) -> Embed:
"""Build a basic embed with red colour and either a random error title or a title provided."""
@@ -15,3 +19,22 @@ def create_error_embed(message: str, title: Iterable | str = ERROR_REPLIES) -> E
embed.title = random.choice(title)
embed.description = message
return embed
+
+
+def revert_cooldown_counter(command: commands.Command, message: Message) -> None:
+ """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)
+ log.debug("Cooldown counter reverted as the command was not used correctly.")
+
+
+def get_parent_command_and_subcontext(context: commands.Context) -> tuple[str, commands.Context]:
+ """Extracts the parent command and subcontext, if any."""
+ parent_command = ""
+ ctx = context
+ if sub_context := getattr(context, "subcontext", None):
+ parent_command = f"{context.command} "
+ ctx = sub_context
+
+ return parent_command, ctx
diff --git a/bot/command_error_handlers/user_input_error.py b/bot/command_error_handlers/user_input_error.py
new file mode 100644
index 00000000..3f99da49
--- /dev/null
+++ b/bot/command_error_handlers/user_input_error.py
@@ -0,0 +1,32 @@
+from typing import NoReturn
+
+from discord import Interaction
+from discord.ext.commands import Context, UserInputError
+from pydis_core.utils.error_handling.commands import AbstractCommandErrorHandler
+
+from ._utils import create_error_embed, get_parent_command_and_subcontext, revert_cooldown_counter
+
+
+class UserInputErrorHandler(AbstractCommandErrorHandler):
+ """An handler for the UserInputError error."""
+
+ async def should_handle_error(self, error: Exception) -> bool:
+ """A predicate that determines whether the error should be handled or not."""
+ return isinstance(error, UserInputError)
+
+ async def handle_text_command_error(self, context: Context, error: Exception) -> NoReturn:
+ """Handle error raised in the context of text commands."""
+ revert_cooldown_counter(context.command, context.message)
+ parent_command, ctx = get_parent_command_and_subcontext(context)
+ usage = f"```\n{ctx.prefix}{parent_command}{ctx.command} {ctx.command.signature}\n```"
+ embed = create_error_embed(
+ f"Your input was invalid: {error}\n\nUsage:{usage}"
+ )
+ await context.send(embed=embed)
+
+ async def handle_app_command_error(self, interaction: Interaction, error: Exception) -> NoReturn:
+ """Handle error raised in the context of app commands."""
+ embed = create_error_embed(
+ f"Your input was invalid: {error}\n"
+ )
+ await interaction.response.send_message(embed=embed)
diff --git a/bot/exts/core/error_handler.py b/bot/exts/core/error_handler.py
index 0e5d60fc..e9a9d768 100644
--- a/bot/exts/core/error_handler.py
+++ b/bot/exts/core/error_handler.py
@@ -67,15 +67,6 @@ class CommandErrorHandler(commands.Cog):
await ctx.send(embed=self.error_embed(str(error), NEGATIVE_REPLIES), delete_after=7.5)
return
- if isinstance(error, commands.UserInputError):
- self.revert_cooldown_counter(ctx.command, ctx.message)
- usage = f"```\n{ctx.prefix}{parent_command}{ctx.command} {ctx.command.signature}\n```"
- embed = self.error_embed(
- f"Your input was invalid: {error}\n\nUsage:{usage}"
- )
- await ctx.send(embed=embed)
- return
-
if isinstance(error, commands.CommandOnCooldown):
mins, secs = divmod(math.ceil(error.retry_after), 60)
embed = self.error_embed(