aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/exts/evergreen/error_handler.py35
1 files changed, 35 insertions, 0 deletions
diff --git a/bot/exts/evergreen/error_handler.py b/bot/exts/evergreen/error_handler.py
index 28902503..d5069168 100644
--- a/bot/exts/evergreen/error_handler.py
+++ b/bot/exts/evergreen/error_handler.py
@@ -1,3 +1,4 @@
+import difflib
import logging
import math
import random
@@ -5,6 +6,7 @@ from typing import Iterable, Union
from discord import Embed, Message
from discord.ext import commands
+from discord.ext.commands import errors
from sentry_sdk import push_scope
from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES
@@ -14,6 +16,9 @@ from bot.utils.exceptions import UserNotPlayingError
log = logging.getLogger(__name__)
+QUESTION_MARK_ICON = "https://cdn.discordapp.com/emojis/512367613339369475.png"
+
+
class CommandErrorHandler(commands.Cog):
"""A error handler for the PythonDiscord server."""
@@ -55,6 +60,7 @@ class CommandErrorHandler(commands.Cog):
)
if isinstance(error, commands.CommandNotFound):
+ await self.send_command_suggestion(ctx, ctx.invoked_with)
return
if isinstance(error, (InChannelCheckFailure, InMonthCheckFailure)):
@@ -128,6 +134,35 @@ class CommandErrorHandler(commands.Cog):
log.exception(f"Unhandled command error: {str(error)}", exc_info=error)
+ async def send_command_suggestion(self, ctx: commands.Context, command_name: str) -> None:
+ """Sends user similar commands if any can be found."""
+ raw_commands = []
+ for cmd in self.bot.walk_commands():
+ if not cmd.hidden:
+ raw_commands += (cmd.name, *cmd.aliases)
+ if similar_command_data := difflib.get_close_matches(command_name, raw_commands, 1):
+ similar_command_name = similar_command_data[0]
+ similar_command = self.bot.get_command(similar_command_name)
+
+ if not similar_command:
+ return
+
+ log_msg = "Cancelling attempt to suggest a command due to failed checks."
+ try:
+ if not await similar_command.can_run(ctx):
+ log.debug(log_msg)
+ return
+ except errors.CommandError as cmd_error:
+ log.debug(log_msg)
+ await self.on_command_error(ctx, cmd_error)
+ return
+
+ misspelled_content = ctx.message.content
+ e = Embed()
+ e.set_author(name="Did you mean:", icon_url=QUESTION_MARK_ICON)
+ e.description = f"{misspelled_content.replace(command_name, similar_command_name, 1)}"
+ await ctx.send(embed=e, delete_after=10.0)
+
def setup(bot: commands.Bot) -> None:
"""Error handler Cog load."""