aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/evergreen/error_handler.py
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/evergreen/error_handler.py')
-rw-r--r--bot/exts/evergreen/error_handler.py36
1 files changed, 35 insertions, 1 deletions
diff --git a/bot/exts/evergreen/error_handler.py b/bot/exts/evergreen/error_handler.py
index de8e53d0..cd53f932 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
@@ -8,13 +9,16 @@ from discord.ext import commands
from sentry_sdk import push_scope
from bot.bot import Bot
-from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES
+from bot.constants import Channels, Colours, ERROR_REPLIES, NEGATIVE_REPLIES, RedirectOutput
from bot.utils.decorators import InChannelCheckFailure, InMonthCheckFailure
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."""
@@ -58,6 +62,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)):
@@ -129,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 commands.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 = misspelled_content.replace(command_name, similar_command_name, 1)
+ await ctx.send(embed=e, delete_after=RedirectOutput.delete_delay)
+
def setup(bot: Bot) -> None:
"""Load the ErrorHandler cog."""