mirror of
https://github.com/wlinator/luminara.git
synced 2024-10-02 18:23:12 +00:00
Working error handler and xkcd commands
This commit is contained in:
parent
47e7d7ad71
commit
24b84c11f2
5 changed files with 177 additions and 7 deletions
140
handlers/error.py
Normal file
140
handlers/error.py
Normal file
|
@ -0,0 +1,140 @@
|
|||
import sys
|
||||
import traceback
|
||||
|
||||
from discord.ext import commands
|
||||
from discord.ext.commands import Cog
|
||||
from loguru import logger
|
||||
|
||||
from lib.const import CONST
|
||||
from ui.embeds import builder
|
||||
from lib import exceptions as LumiExceptions
|
||||
|
||||
|
||||
async def handle_error(
|
||||
ctx: commands.Context[commands.Bot],
|
||||
error: commands.CommandError | commands.CheckFailure,
|
||||
) -> None:
|
||||
if isinstance(error, (commands.CommandNotFound, LumiExceptions.Blacklisted)):
|
||||
return
|
||||
|
||||
author_text = None
|
||||
description = None
|
||||
footer_text = None
|
||||
ephemeral = False
|
||||
|
||||
if isinstance(error, commands.MissingRequiredArgument):
|
||||
author_text = CONST.STRINGS["error_bad_argument_author"]
|
||||
description = CONST.STRINGS["error_bad_argument_description"].format(str(error))
|
||||
|
||||
elif isinstance(error, commands.BadArgument):
|
||||
author_text = CONST.STRINGS["error_bad_argument_author"]
|
||||
description = CONST.STRINGS["error_bad_argument_description"].format(str(error))
|
||||
|
||||
elif isinstance(error, commands.BotMissingPermissions):
|
||||
author_text = CONST.STRINGS["error_bot_missing_permissions_author"]
|
||||
description = CONST.STRINGS["error_bot_missing_permissions_description"]
|
||||
|
||||
elif isinstance(error, commands.CommandOnCooldown):
|
||||
author_text = CONST.STRINGS["error_command_cooldown_author"]
|
||||
description = CONST.STRINGS["error_command_cooldown_description"].format(
|
||||
int(error.retry_after // 60),
|
||||
int(error.retry_after % 60),
|
||||
)
|
||||
ephemeral = True
|
||||
|
||||
elif isinstance(error, commands.MissingPermissions):
|
||||
author_text = CONST.STRINGS["error_missing_permissions_author"]
|
||||
description = CONST.STRINGS["error_missing_permissions_description"]
|
||||
|
||||
elif isinstance(error, commands.NoPrivateMessage):
|
||||
author_text = CONST.STRINGS["error_no_private_message_author"]
|
||||
description = CONST.STRINGS["error_no_private_message_description"]
|
||||
|
||||
elif isinstance(error, commands.NotOwner):
|
||||
author_text = CONST.STRINGS["error_not_owner_author"]
|
||||
description = CONST.STRINGS["error_not_owner_description"]
|
||||
|
||||
elif isinstance(error, commands.PrivateMessageOnly):
|
||||
author_text = CONST.STRINGS["error_private_message_only_author"]
|
||||
description = CONST.STRINGS["error_private_message_only_description"]
|
||||
|
||||
elif isinstance(error, LumiExceptions.BirthdaysDisabled):
|
||||
author_text = CONST.STRINGS["error_birthdays_disabled_author"]
|
||||
description = CONST.STRINGS["error_birthdays_disabled_description"]
|
||||
footer_text = CONST.STRINGS["error_birthdays_disabled_footer"]
|
||||
|
||||
elif isinstance(error, LumiExceptions.LumiException):
|
||||
author_text = CONST.STRINGS["error_lumi_exception_author"]
|
||||
description = CONST.STRINGS["error_lumi_exception_description"].format(
|
||||
str(error),
|
||||
)
|
||||
|
||||
else:
|
||||
author_text = CONST.STRINGS["error_unknown_error_author"]
|
||||
description = CONST.STRINGS["error_unknown_error_description"]
|
||||
|
||||
await ctx.send(
|
||||
embed=builder.create_error_embed(
|
||||
ctx,
|
||||
author_text=author_text,
|
||||
description=description,
|
||||
footer_text=footer_text,
|
||||
),
|
||||
ephemeral=ephemeral,
|
||||
)
|
||||
|
||||
|
||||
async def on_error(event: str, *args, **kwargs) -> None:
|
||||
logger.exception(
|
||||
f"on_error INFO: errors.event.{event} | '*args': {args} | '**kwargs': {kwargs}",
|
||||
)
|
||||
logger.exception(f"on_error EXCEPTION: {sys.exc_info()}")
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
class ErrorHandler(Cog):
|
||||
def __init__(self, bot: commands.Bot) -> None:
|
||||
self.bot = bot
|
||||
|
||||
@staticmethod
|
||||
async def log_command_error(ctx, error, command_type):
|
||||
log_msg = (
|
||||
f"{ctx.author.name} executed {command_type}{ctx.command.qualified_name}"
|
||||
)
|
||||
|
||||
log_msg += " in DMs" if ctx.guild is None else f" | guild: {ctx.guild.name} "
|
||||
logger.exception(f"{log_msg} | FAILED: {error}")
|
||||
|
||||
@Cog.listener()
|
||||
async def on_command_error(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
error: commands.CommandError | commands.CheckFailure,
|
||||
) -> None:
|
||||
try:
|
||||
await handle_error(ctx, error)
|
||||
await self.log_command_error(ctx, error, ".")
|
||||
except Exception as e:
|
||||
logger.exception(f"Error in on_command_error: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
@Cog.listener()
|
||||
async def on_app_command_error(
|
||||
self,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
error: commands.CommandError | commands.CheckFailure,
|
||||
) -> None:
|
||||
try:
|
||||
await handle_error(ctx, error)
|
||||
await self.log_command_error(ctx, error, "/")
|
||||
except Exception as e:
|
||||
logger.exception(f"Error in on_app_command_error: {e}")
|
||||
traceback.print_exc()
|
||||
|
||||
@Cog.listener()
|
||||
async def on_error(self, event: str, *args, **kwargs) -> None:
|
||||
await on_error(event, *args, **kwargs)
|
||||
|
||||
|
||||
async def setup(bot: commands.Bot) -> None:
|
||||
await bot.add_cog(ErrorHandler(bot))
|
31
lib/exceptions.py
Normal file
31
lib/exceptions.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
from discord.ext import commands
|
||||
|
||||
from lib.const import CONST
|
||||
|
||||
|
||||
class BirthdaysDisabled(commands.CheckFailure):
|
||||
"""
|
||||
Raised when the birthdays module is disabled in ctx.guild.
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class LumiException(commands.CommandError):
|
||||
"""
|
||||
A generic exception to raise for quick error handling.
|
||||
"""
|
||||
|
||||
def __init__(self, message=CONST.STRINGS["lumi_exception_generic"]):
|
||||
self.message = message
|
||||
super().__init__(message)
|
||||
|
||||
|
||||
class Blacklisted(commands.CommandError):
|
||||
"""
|
||||
Raised when a user is blacklisted.
|
||||
"""
|
||||
|
||||
def __init__(self, message=CONST.STRINGS["lumi_exception_blacklisted"]):
|
||||
self.message = message
|
||||
super().__init__(message)
|
|
@ -52,4 +52,5 @@ class CogLoader(commands.Cog):
|
|||
async def setup(cls, bot: commands.Bot) -> None:
|
||||
cog_loader = cls(bot)
|
||||
await cog_loader.load_cog_from_dir(dir_name="modules")
|
||||
await cog_loader.load_cog_from_dir(dir_name="handlers")
|
||||
await bot.add_cog(cog_loader)
|
||||
|
|
|
@ -22,7 +22,7 @@ async def print_comic(
|
|||
else:
|
||||
comic = _xkcd.get_random_comic(raw_comic_image=True)
|
||||
|
||||
await interaction.followup.send(
|
||||
await interaction.response.send_message(
|
||||
embed=builder.create_success_embed(
|
||||
interaction,
|
||||
author_text=CONST.STRINGS["xkcd_title"].format(comic.id, comic.title),
|
||||
|
@ -37,7 +37,7 @@ async def print_comic(
|
|||
)
|
||||
|
||||
except HttpError:
|
||||
await interaction.followup.send(
|
||||
await interaction.response.send_message(
|
||||
embed=builder.create_error_embed(
|
||||
interaction,
|
||||
author_text=CONST.STRINGS["xkcd_not_found_author"],
|
||||
|
@ -51,10 +51,7 @@ class Xkcd(commands.Cog):
|
|||
def __init__(self, bot: commands.Bot):
|
||||
self.bot = bot
|
||||
|
||||
xkcd: app_commands.Group = app_commands.Group(
|
||||
name="xkcd",
|
||||
description="Xkcd commands",
|
||||
)
|
||||
xkcd = app_commands.Group(name="xkcd", description="Get the latest xkcd comic")
|
||||
|
||||
@xkcd.command(name="latest", description="Get the latest xkcd comic")
|
||||
async def xkcd_latest(self, interaction: discord.Interaction) -> None:
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import datetime
|
||||
|
||||
from discord.ext import commands
|
||||
import discord
|
||||
|
||||
from lib.const import CONST
|
||||
|
@ -8,7 +9,7 @@ from lib.const import CONST
|
|||
class builder:
|
||||
@staticmethod
|
||||
def create_embed(
|
||||
ctx,
|
||||
ctx: commands.Context[commands.Bot],
|
||||
title=None,
|
||||
author_text=None,
|
||||
author_icon_url=None,
|
||||
|
|
Loading…
Reference in a new issue