aboutsummaryrefslogtreecommitdiffstats
path: root/bot/exts/backend
diff options
context:
space:
mode:
Diffstat (limited to 'bot/exts/backend')
-rw-r--r--bot/exts/backend/error_handler.py46
1 files changed, 44 insertions, 2 deletions
diff --git a/bot/exts/backend/error_handler.py b/bot/exts/backend/error_handler.py
index 0aeffe290..9398aa8ec 100644
--- a/bot/exts/backend/error_handler.py
+++ b/bot/exts/backend/error_handler.py
@@ -1,4 +1,5 @@
import contextlib
+import difflib
import logging
import random
import typing as t
@@ -9,7 +10,7 @@ from sentry_sdk import push_scope
from bot.api import ResponseCodeError
from bot.bot import Bot
-from bot.constants import Colours, ERROR_REPLIES
+from bot.constants import Colours, ERROR_REPLIES, Icons, MODERATION_ROLES
from bot.converters import TagNameConverter
from bot.errors import LockedResourceError
from bot.exts.backend.branding._errors import BrandingError
@@ -159,10 +160,51 @@ class ErrorHandler(Cog):
)
else:
with contextlib.suppress(ResponseCodeError):
- await ctx.invoke(tags_get_command, tag_name=tag_name)
+ if await ctx.invoke(tags_get_command, tag_name=tag_name):
+ return
+
+ if not any(role.id in MODERATION_ROLES for role in ctx.author.roles):
+ tags_cog = self.bot.get_cog("Tags")
+ command_name = ctx.invoked_with
+ sent = await tags_cog.display_tag(ctx, command_name)
+
+ if not sent:
+ await self.send_command_suggestion(ctx, command_name)
+
# Return to not raise the exception
return
+ async def send_command_suggestion(self, ctx: Context, command_name: str) -> None:
+ """Sends user similar commands if any can be found."""
+ # No similar tag found, or tag on cooldown -
+ # searching for a similar command
+ 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=Icons.questionmark)
+ e.description = f"{misspelled_content.replace(command_name, similar_command_name, 1)}"
+ await ctx.send(embed=e, delete_after=10.0)
+
async def handle_user_input_error(self, ctx: Context, e: errors.UserInputError) -> None:
"""
Send an error message in `ctx` for UserInputError, sometimes invoking the help command too.