From 38c0a470860954cd56ee076db57539e9b82320b6 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Wed, 16 Feb 2022 11:09:17 -0700 Subject: [PATCH] Fix dev cog, add error logging --- jarvis/__init__.py | 90 +++++++++++++++++++++++++++++++++++--------- jarvis/cogs/dev.py | 8 +++- jarvis/cogs/error.py | 56 --------------------------- 3 files changed, 79 insertions(+), 75 deletions(-) delete mode 100644 jarvis/cogs/error.py diff --git a/jarvis/__init__.py b/jarvis/__init__.py index c1537ad..733cdbb 100644 --- a/jarvis/__init__.py +++ b/jarvis/__init__.py @@ -1,8 +1,12 @@ """Main J.A.R.V.I.S. package.""" +import json import logging +import traceback +from datetime import datetime -from dis_snek import Intents, Snake, listen -from mongoengine import connect +from aiohttp import ClientSession +from dis_snek import Context, Intents, Snake, listen +from jarvis_core.db import connect # from jarvis import logo # noqa: F401 from jarvis import tasks, utils @@ -17,12 +21,75 @@ file_handler = logging.FileHandler(filename="jarvis.log", encoding="UTF-8", mode file_handler.setFormatter(logging.Formatter("[%(asctime)s][%(levelname)s][%(name)s] %(message)s")) logger.addHandler(file_handler) -intents = Intents.DEFAULT -intents.members = True +intents = Intents.DEFAULT | Intents.MESSAGES | Intents.GUILD_MEMBERS restart_ctx = None +DEFAULT_GUILD = 862402786116763668 +DEFAULT_ERROR_CHANNEL = 943395824560394250 +DEFAULT_URL = "https://paste.zevs.me/documents" -jarvis = Snake(intents=intents, default_prefix="!", sync_interactions=jconfig.sync) +ERROR_MSG = """ +Command Information: + Name: {invoked_name} + Args: +{arg_str} + +Callback: + Args: +{callback_args} + Kwargs: +{callback_kwargs} +""" + + +class Jarvis(Snake): + async def on_command_error( + self, ctx: Context, error: Exception, *args: list, **kwargs: dict + ) -> None: + """Lepton on_command_error override.""" + guild = await jarvis.get_guild(DEFAULT_GUILD) + channel = guild.get_channel(DEFAULT_ERROR_CHANNEL) + error_time = datetime.utcnow().strftime("%d-%m-%Y %H:%M-%S.%f UTC") + timestamp = int(datetime.now().timestamp()) + timestamp = f"" + arg_str = ( + "\n".join(f" {k}: {v}" for k, v in ctx.kwargs.items()) if ctx.kwargs else " None" + ) + callback_args = "\n".join(f" - {i}" for i in args) if args else " None" + callback_kwargs = ( + "\n".join(f" {k}: {v}" for k, v in kwargs.items()) if kwargs else " None" + ) + full_message = ERROR_MSG.format( + error_time=error_time, + invoked_name=ctx.invoked_name, + arg_str=arg_str, + callback_args=callback_args, + callback_kwargs=callback_kwargs, + ) + if len(full_message) >= 1900: + error_message = " ".join(traceback.format_exception(error)) + full_message += "Exception: |\n " + error_message + async with ClientSession() as session: + resp = await session.post(DEFAULT_URL, data=full_message) + data = await resp.read() + data = json.loads(data.decode("UTF8")) + + await channel.send( + f"JARVIS encountered an error at {timestamp}. Log too big to send over Discord." + f"\nPlease see log at https://paste.zevs.me/{data['key']}" + ) + else: + error_message = "".join(traceback.format_exception(error)) + await channel.send( + f"JARVIS encountered an error at {timestamp}:" + f"\n```yaml\n{full_message}\n```" + f"\nException:\n```py\n{error_message}\n```" + ) + await ctx.send("Whoops! Encountered an error. The error has been logged.", ephemeral=True) + return await super().on_command_error(ctx, error, *args, **kwargs) + + +jarvis = Jarvis(intents=intents, default_prefix="!", sync_interactions=jconfig.sync) __version__ = "2.0.0a1" @@ -43,18 +110,7 @@ async def on_startup() -> None: def run() -> None: """Run J.A.R.V.I.S.""" - connect( - db="ctc2", - alias="ctc2", - authentication_source="admin", - **jconfig.mongo["connect"], - ) - connect( - db=jconfig.mongo["database"], - alias="main", - authentication_source="admin", - **jconfig.mongo["connect"], - ) + connect(**jconfig.mongo["connect"], testing=jconfig.mongo["database"] == "jarvis") jconfig.get_db_config() for extension in utils.get_extensions(): diff --git a/jarvis/cogs/dev.py b/jarvis/cogs/dev.py index ab26c05..f867100 100644 --- a/jarvis/cogs/dev.py +++ b/jarvis/cogs/dev.py @@ -82,8 +82,12 @@ class DevCog(Scale): data = attach.url title = attach.filename elif url.match(data): - if await get_size(data) > MAX_FILESIZE: - await ctx.send("Please hash files that are <= 5GB in size", ephemeral=True) + try: + if await get_size(data) > MAX_FILESIZE: + await ctx.send("Please hash files that are <= 5GB in size", ephemeral=True) + return + except Exception as e: + await ctx.send(f"Failed to retrieve URL: ```\n{e}\n```", ephemeral=True) return title = data.split("/")[-1] diff --git a/jarvis/cogs/error.py b/jarvis/cogs/error.py deleted file mode 100644 index d245b0c..0000000 --- a/jarvis/cogs/error.py +++ /dev/null @@ -1,56 +0,0 @@ -"""J.A.R.V.I.S. error handling cog.""" -from discord.ext import commands -from discord_slash import SlashContext - -from jarvis import slash - - -class ErrorHandlerCog(commands.Cog): - """J.A.R.V.I.S. error handling cog.""" - - def __init__(self, bot: commands.Bot): - self.bot = bot - - @commands.Cog.listener() - async def on_command_error(self, ctx: commands.Context, error: Exception) -> None: - """d.py on_command_error override.""" - if isinstance(error, commands.errors.MissingPermissions): - await ctx.send("I'm afraid I can't let you do that.") - elif isinstance(error, commands.errors.CommandNotFound): - return - elif isinstance(error, commands.errors.CommandOnCooldown): - await ctx.send( - "Command on cooldown. " - f"Please wait {error.retry_after:0.2f}s before trying again", - ) - else: - await ctx.send(f"Error processing command:\n```{error}```") - ctx.command.reset_cooldown(ctx) - - @commands.Cog.listener() - async def on_slash_command_error(self, ctx: SlashContext, error: Exception) -> None: - """discord_slash on_slash_command_error override.""" - if isinstance(error, commands.errors.MissingPermissions) or isinstance( - error, commands.errors.CheckFailure - ): - await ctx.send("I'm afraid I can't let you do that.", ephemeral=True) - elif isinstance(error, commands.errors.CommandNotFound): - return - elif isinstance(error, commands.errors.CommandOnCooldown): - await ctx.send( - "Command on cooldown. " - f"Please wait {error.retry_after:0.2f}s before trying again", - ephemeral=True, - ) - else: - await ctx.send( - f"Error processing command:\n```{error}```", - ephemeral=True, - ) - raise error - slash.commands[ctx.command].reset_cooldown(ctx) - - -def setup(bot: commands.Bot) -> None: - """Add ErrorHandlerCog to J.A.R.V.I.S.""" - ErrorHandlerCog(bot)