From 8a3c78232f455ce2cc0aeaa61c714f306a42f5b5 Mon Sep 17 00:00:00 2001 From: wlinator Date: Tue, 19 Mar 2024 08:46:52 +0100 Subject: [PATCH] Create ErrorHandler to handle both prefix and slash errors --- handlers/ErrorHandler.py | 49 ++++++++++++++++++++++++++++++++++++++++ main.py | 43 +++++++---------------------------- modules/misc/__init__.py | 3 +-- 3 files changed, 58 insertions(+), 37 deletions(-) create mode 100644 handlers/ErrorHandler.py diff --git a/handlers/ErrorHandler.py b/handlers/ErrorHandler.py new file mode 100644 index 0000000..03e7a7f --- /dev/null +++ b/handlers/ErrorHandler.py @@ -0,0 +1,49 @@ +import logging +import traceback +import sys + +import discord +from discord.ext import commands +from lib.embeds.error import GenericErrors + +logs = logging.getLogger('Racu.Core') + + +async def on_command_error(ctx, error): + if isinstance(error, commands.CommandOnCooldown): + + seconds = error.retry_after + minutes = seconds // 60 + seconds %= 60 + cooldown = "{:02d}:{:02d}".format(int(minutes), int(seconds)) + + await ctx.respond(embed=GenericErrors.command_on_cooldown(ctx, cooldown)) + + elif isinstance(error, commands.MissingPermissions): + await ctx.respond(embed=GenericErrors.missing_permissions(ctx)) + + elif isinstance(error, commands.BotMissingPermissions): + await ctx.respond(embed=GenericErrors.bot_missing_permissions(ctx)) + + elif isinstance(error, commands.PrivateMessageOnly): + await ctx.respond(embed=GenericErrors.private_message_only(ctx)) + + elif isinstance(error, commands.NoPrivateMessage): + await ctx.respond(embed=GenericErrors.guild_only(ctx)) + + elif isinstance(error, (discord.CheckFailure, commands.CheckFailure)): + logs.info(f"[CommandHandler] {ctx.author.name} check failure: \"/{ctx.command.qualified_name}\"") + + elif isinstance(error, (commands.MissingRequiredArgument, commands.BadArgument, commands.CommandNotFound)): + pass + + else: + await ctx.respond(embed=GenericErrors.default_exception(ctx)) + traceback.print_tb(error.original.__traceback__) + + logs.error(f"[CommandHandler] on_command_error: {error}") + + +async def on_error(event: str, *args, **kwargs) -> None: + logs.error(f"[EventHandler] on_error INFO: errors.event.{event} | '*args': {args} | '**kwargs': {kwargs}") + logs.error(f"[EventHandler] on_error EXCEPTION: {sys.exc_info()}") \ No newline at end of file diff --git a/main.py b/main.py index b1ab006..a8e9aeb 100644 --- a/main.py +++ b/main.py @@ -12,7 +12,7 @@ from lib.embeds.greet import Greet from config import json_loader from handlers.ReactionHandler import ReactionHandler from handlers.XPHandler import XPHandler -from handlers import LoggingHandler +from handlers import LoggingHandler, ErrorHandler from services.GuildConfig import GuildConfig from services.Help import RacuHelp @@ -94,7 +94,7 @@ async def on_member_join(member): logs.info(f"[GreetingHandler] Message not sent in '{member.guild.name}'. Channel ID may be invalid. {e}") -@client.event +@client.listen() async def on_command_completion(ctx) -> None: """ This code is executed when a slash_command has been successfully executed. @@ -120,46 +120,19 @@ async def on_command_completion(ctx) -> None: logs.info(f"[CommandHandler] {ctx.author.name} successfully did \"/{executed_command}\". | direct message") -@client.event +@client.listen() async def on_command_error(ctx, error) -> None: - if isinstance(error, commands.CommandOnCooldown): + await ErrorHandler.on_command_error(ctx, error) - seconds = error.retry_after - minutes = seconds // 60 - seconds %= 60 - cooldown = "{:02d}:{:02d}".format(int(minutes), int(seconds)) - await ctx.respond(embed=GenericErrors.command_on_cooldown(ctx, cooldown)) - - elif isinstance(error, commands.MissingPermissions): - await ctx.respond(embed=GenericErrors.missing_permissions(ctx)) - - elif isinstance(error, commands.BotMissingPermissions): - await ctx.respond(embed=GenericErrors.bot_missing_permissions(ctx)) - - elif isinstance(error, commands.PrivateMessageOnly): - await ctx.respond(embed=GenericErrors.private_message_only(ctx)) - - elif isinstance(error, commands.NoPrivateMessage): - await ctx.respond(embed=GenericErrors.guild_only(ctx)) - - elif isinstance(error, (discord.CheckFailure, commands.CheckFailure)): - logs.info(f"[CommandHandler] {ctx.author.name} check failure: \"/{ctx.command.qualified_name}\"") - - elif isinstance(error, (commands.MissingRequiredArgument, commands.BadArgument, commands.CommandNotFound)): - pass - - else: - await ctx.respond(embed=GenericErrors.default_exception(ctx)) - traceback.print_tb(error.original.__traceback__) - - logs.error(f"[CommandHandler] on_command_error: {error}") +@client.listen() +async def on_application_command_error(ctx, error) -> None: + await ErrorHandler.on_command_error(ctx, error) @client.event async def on_error(event: str, *args, **kwargs) -> None: - logs.error(f"[EventHandler] on_error INFO: errors.event.{event} | '*args': {args} | '**kwargs': {kwargs}") - logs.error(f"[EventHandler] on_error EXCEPTION: {sys.exc_info()}") + await ErrorHandler.on_error(event, *args, **kwargs) # load all json diff --git a/modules/misc/__init__.py b/modules/misc/__init__.py index 13835fa..321960e 100644 --- a/modules/misc/__init__.py +++ b/modules/misc/__init__.py @@ -18,7 +18,6 @@ class Misc(commands.Cog): description="Simple status check.", help="Simple status check, this command will not return the latency of the bot process as this is " "fairly irrelevant. If the bot replies, it's good to go.", - guild_only=True ) @commands.check(checks.channel) async def ping(self, ctx): @@ -28,8 +27,8 @@ class Misc(commands.Cog): name="uptime", description="Racu uptime", help="See how long Racu has been online, the uptime shown will reset when the Misc module is reloaded.", - guild_only=True ) + @commands.guild_only() @commands.check(checks.channel) async def uptime(self, ctx):