Skip to content

Commit f51d537

Browse files
resolve bug in github code and add basic error handling (#24)
1 parent 837f35a commit f51d537

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

core/bot.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@
2222
"""
2323
from __future__ import annotations
2424

25+
import datetime
2526
import json
2627
import pathlib
28+
import sys
29+
import textwrap
30+
import traceback
2731
from collections import deque
2832
from typing import TYPE_CHECKING, Any
2933

@@ -82,6 +86,55 @@ async def on_socket_response(self, message: Any) -> None:
8286
"""Quick override to log websocket events."""
8387
self._previous_websocket_events.append(message)
8488

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+
85138
async def start(self, token: str, *, reconnect: bool = True) -> None:
86139
try:
87140
await super().start(token=token, reconnect=reconnect)

modules/github.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232

3333
GITHUB_ISSUE_URL = "https://github.com/{}/issues/{}"
3434
LIB_ISSUE_REGEX = re.compile(r"(?P<lib>[a-z]+)?##(?P<number>[0-9]+)", flags=re.IGNORECASE)
35+
GITHUB_CODE_REGION_REGEX = re.compile(
36+
r"https?://github\.com/(?P<user>.*)/(?P<repo>.*)/blob/(?P<hash>[a-zA-Z0-9]+)/(?P<path>.*)(?:\#L)(?P<linestart>[0-9]+)(?:-L)?(?P<lineend>[0-9]+)?"
37+
)
3538

3639
GITHUB_BASE_URL = "https://github.com/"
3740
GITHUB_RAW_CONTENT_URL = "https://raw.githubusercontent.com/"
@@ -56,8 +59,13 @@ def _strip_content_path(self, url: str) -> str:
5659
return file_path
5760

5861
async def format_highlight_block(self, url: str, line_adjustment: int = 10) -> dict[str, str | int] | None:
62+
match = GITHUB_CODE_REGION_REGEX.search(url)
63+
64+
if not match:
65+
return
66+
5967
try:
60-
highlighted_line = int(url.split("#L")[1]) # separate the #L{n} highlight
68+
highlighted_line = int(match["linestart"]) # separate the #L{n} highlight
6169
except IndexError:
6270
return
6371

modules/logging.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,21 @@ async def logging_loop(self) -> None:
5454
assert self.webhook
5555

5656
to_log = await self.bot.logging_queue.get()
57+
5758
attributes = {"INFO": "\U00002139\U0000fe0f", "WARNING": "\U000026a0\U0000fe0f"}
5859

5960
emoji = attributes.get(to_log.levelname, "\N{CROSS MARK}")
6061
dt = datetime.datetime.utcfromtimestamp(to_log.created)
6162

6263
message = textwrap.shorten(f"{emoji} {format_dt(dt)}\n{to_log.message}", width=1990)
6364

65+
embed = to_log.__dict__.get("embed") or discord.utils.MISSING
66+
6467
await self.webhook.send(
6568
message,
6669
username="PythonistaBot Logging",
6770
avatar_url=core.CONFIG["LOGGING"].get("webhook_avatar_url"),
71+
embed=embed,
6872
)
6973

7074

0 commit comments

Comments
 (0)