|
22 | 22 | """
|
23 | 23 | from __future__ import annotations
|
24 | 24 |
|
| 25 | +import datetime |
25 | 26 | import json
|
26 | 27 | import pathlib
|
| 28 | +import sys |
| 29 | +import textwrap |
| 30 | +import traceback |
27 | 31 | from collections import deque
|
28 | 32 | from typing import TYPE_CHECKING, Any
|
29 | 33 |
|
@@ -82,6 +86,55 @@ async def on_socket_response(self, message: Any) -> None:
|
82 | 86 | """Quick override to log websocket events."""
|
83 | 87 | self._previous_websocket_events.append(message)
|
84 | 88 |
|
| 89 | + async def on_error(self, event_name: str, /, *args: Any, **kwargs: Any) -> None: |
| 90 | + exc_type, exception, traceback_ = sys.exc_info() |
| 91 | + |
| 92 | + if isinstance(exception, commands.CommandInvokeError): |
| 93 | + return |
| 94 | + |
| 95 | + embed = discord.Embed(title="Event Error", colour=discord.Colour.random()) |
| 96 | + embed.add_field(name="Event", value=event_name) |
| 97 | + |
| 98 | + traceback_text = "".join(traceback.format_exception(exc_type, exception, traceback_)) |
| 99 | + |
| 100 | + embed.description = f"```py\n{traceback_text}\n```" |
| 101 | + embed.timestamp = datetime.datetime.now(datetime.timezone.utc) |
| 102 | + |
| 103 | + args_str = ["```py"] |
| 104 | + for index, arg in enumerate(args): |
| 105 | + args_str.append(f"[{index}]: {arg!r}") |
| 106 | + args_str.append("```") |
| 107 | + embed.add_field(name="Args", value="\n".join(args_str), inline=False) |
| 108 | + |
| 109 | + self.log_handler.error("Event Error", extra={"embed": embed}) |
| 110 | + |
| 111 | + async def on_command_error(self, ctx: Context, error: commands.CommandError) -> None: # type: ignore # weird narrowing |
| 112 | + assert ctx.command # wouldn't be here otherwise |
| 113 | + |
| 114 | + if not isinstance(error, (commands.CommandInvokeError, commands.ConversionError)): |
| 115 | + return |
| 116 | + |
| 117 | + error = getattr(error, "original", error) |
| 118 | + if isinstance(error, (discord.Forbidden, discord.NotFound)): |
| 119 | + return |
| 120 | + |
| 121 | + embed = discord.Embed(title="Command Error", colour=0xCC3366) |
| 122 | + embed.add_field(name="Name", value=ctx.command.qualified_name) |
| 123 | + embed.add_field(name="Author", value=f"{ctx.author} (ID: {ctx.author.id})") |
| 124 | + |
| 125 | + fmt = f"Channel: {ctx.channel} (ID: {ctx.channel.id})" |
| 126 | + if ctx.guild: |
| 127 | + fmt = f"{fmt}\nGuild: {ctx.guild} (ID: {ctx.guild.id})" |
| 128 | + |
| 129 | + embed.add_field(name="Location", value=fmt, inline=False) |
| 130 | + embed.add_field(name="Content", value=textwrap.shorten(ctx.message.content, width=512)) |
| 131 | + |
| 132 | + exc = "".join(traceback.format_exception(type(error), error, error.__traceback__, chain=False)) |
| 133 | + embed.description = f"```py\n{exc}\n```" |
| 134 | + embed.timestamp = discord.utils.utcnow() |
| 135 | + |
| 136 | + self.log_handler.error("Command Error", extra={"embed": embed}) |
| 137 | + |
85 | 138 | async def start(self, token: str, *, reconnect: bool = True) -> None:
|
86 | 139 | try:
|
87 | 140 | await super().start(token=token, reconnect=reconnect)
|
|
0 commit comments