diff --git a/didier/cogs/tasks.py b/didier/cogs/tasks.py index cf1293e..239f02a 100644 --- a/didier/cogs/tasks.py +++ b/didier/cogs/tasks.py @@ -1,6 +1,5 @@ import datetime import random -import traceback import discord from discord.ext import commands, tasks # type: ignore # Strange & incorrect Mypy error @@ -212,8 +211,7 @@ class Tasks(commands.Cog): await member.send(embed=personal_schedule.to_embed(day=today)) - # @tasks.loop(time=SOCIALLY_ACCEPTABLE_TIME) - @tasks.loop(hours=3) + @tasks.loop(time=SOCIALLY_ACCEPTABLE_TIME) async def reminders(self, **kwargs): """Send daily reminders to people""" _ = kwargs @@ -258,8 +256,7 @@ class Tasks(commands.Cog): @reset_wordle_word.error async def _on_tasks_error(self, error: BaseException): """Error handler for all tasks""" - print("".join(traceback.format_exception(type(error), error, error.__traceback__))) - self.client.dispatch("task_error") + self.client.dispatch("task_error", error) async def setup(client: Didier): diff --git a/didier/data/embeds/error_embed.py b/didier/data/embeds/error_embed.py index 03edd25..70bc2d3 100644 --- a/didier/data/embeds/error_embed.py +++ b/didier/data/embeds/error_embed.py @@ -1,4 +1,5 @@ import traceback +from typing import Optional import discord from discord.ext import commands @@ -18,7 +19,7 @@ def _get_traceback(exception: Exception) -> str: if line.strip().startswith("The above exception was the direct cause of"): break - # Escape Discord markdown formatting + # Escape Discord Markdown formatting error_string += line.replace(r"*", r"\*").replace(r"_", r"\_") if line.strip(): error_string += "\n" @@ -26,23 +27,30 @@ def _get_traceback(exception: Exception) -> str: return abbreviate(error_string, Limits.EMBED_FIELD_VALUE_LENGTH - 8) -def create_error_embed(ctx: commands.Context, exception: Exception) -> discord.Embed: +def create_error_embed(ctx: Optional[commands.Context], exception: Exception) -> discord.Embed: """Create an embed for the traceback of an exception""" + message = str(exception) + # Wrap the traceback in a codeblock for readability description = _get_traceback(exception).strip() description = f"```\n{description}\n```" - if ctx.guild is None: - origin = "DM" - else: - origin = f"{ctx.channel.mention} ({ctx.guild.name})" - - invocation = f"{ctx.author.display_name} in {origin}" - embed = discord.Embed(title="Error", colour=discord.Colour.red()) - embed.add_field(name="Command", value=f"{ctx.message.content}", inline=True) - embed.add_field(name="Context", value=invocation, inline=True) - embed.add_field(name="Exception", value=str(exception), inline=False) + + if ctx is not None: + if ctx.guild is None: + origin = "DM" + else: + origin = f"{ctx.channel.mention} ({ctx.guild.name})" + + invocation = f"{ctx.author.display_name} in {origin}" + + embed.add_field(name="Command", value=f"{ctx.message.content}", inline=True) + embed.add_field(name="Context", value=invocation, inline=True) + + if message: + embed.add_field(name="Exception", value=message, inline=False) + embed.add_field(name="Traceback", value=description, inline=False) return embed diff --git a/didier/data/embeds/logging_embed.py b/didier/data/embeds/logging_embed.py index 784cc3f..40556f2 100644 --- a/didier/data/embeds/logging_embed.py +++ b/didier/data/embeds/logging_embed.py @@ -2,6 +2,9 @@ import logging import discord +from didier.utils.discord.constants import Limits +from didier.utils.types.string import abbreviate + __all__ = ["create_logging_embed"] @@ -16,6 +19,6 @@ def create_logging_embed(level: int, message: str) -> discord.Embed: colour = colours.get(level, discord.Colour.red()) embed = discord.Embed(colour=colour, title="Logging") - embed.description = message + embed.description = abbreviate(message, Limits.EMBED_DESCRIPTION_LENGTH) return embed diff --git a/didier/didier.py b/didier/didier.py index 050def6..cdfa7bd 100644 --- a/didier/didier.py +++ b/didier/didier.py @@ -363,6 +363,13 @@ class Didier(commands.Bot): """Event triggered when the bot is ready""" print(settings.DISCORD_READY_MESSAGE) + async def on_task_error(self, exception: Exception): + """Event triggered when a task raises an exception""" + if settings.ERRORS_CHANNEL is not None: + embed = create_error_embed(None, exception) + channel = self.get_channel(settings.ERRORS_CHANNEL) + await channel.send(embed=embed) + async def on_thread_create(self, thread: discord.Thread): """Event triggered when a new thread is created""" # Join threads automatically