Skip to content

Commit 2371fa2

Browse files
committed
fix: raise exceptions for errors instead of integers
1 parent b2ed216 commit 2371fa2

1 file changed

Lines changed: 40 additions & 23 deletions

File tree

bot/exts/utilities/githubinfo.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@
4848
r"((?P<org>[a-zA-Z0-9][a-zA-Z0-9\-]{1,39})\/)?(?P<repo>[\w\-\.]{1,100})#(?P<number>[0-9]+)"
4949
)
5050

51+
class GithubAPIError(Exception):
52+
"""Raised when GitHub API returns a non 200 status code."""
53+
54+
def __init__(self, status: int, message: str = "GitHub API error"):
55+
self.status = status
56+
self.message = message
57+
super().__init__(f"{message} (Status: {status})")
58+
59+
class StargazersLimitError(Exception):
60+
"""Raised when a repository exceeds the searchable stargazer limit."""
61+
5162

5263
@dataclass(eq=True, frozen=True)
5364
class FoundIssue:
@@ -374,7 +385,7 @@ async def get_issue_count(self, repo: str, start: str, end: str, state: str) ->
374385

375386
async with self.bot.http_session.get(url, headers=REQUEST_HEADERS, params=params) as response:
376387
if response.status != 200:
377-
return -1
388+
raise GithubAPIError(response.status)
378389
data = await response.json()
379390
return data.get("total_count", 0)
380391

@@ -396,7 +407,7 @@ async def get_pr_count(self, repo: str, start: str, end: str, action: str) -> in
396407

397408
async with self.bot.http_session.get(url, headers=REQUEST_HEADERS, params=params) as response:
398409
if response.status != 200:
399-
return -1
410+
raise GithubAPIError(response.status)
400411

401412
data = await response.json()
402413
return data.get("total_count", 0)
@@ -411,7 +422,7 @@ async def get_commit_count(self, repo_str: str, start_str: str, end_str: str) ->
411422

412423
async with self.bot.http_session.get(url, headers=REQUEST_HEADERS, params=params) as response:
413424
if response.status != 200:
414-
return -1
425+
raise GithubAPIError(response.status)
415426

416427
commits_json = await response.json()
417428
# No commits
@@ -437,7 +448,7 @@ async def _fetch_page(self, url: str, headers: dict, page: int, cache: dict) ->
437448
params = {"per_page": 100, "page": page}
438449
async with self.bot.http_session.get(url, headers=headers, params=params) as response:
439450
if response.status != 200:
440-
return []
451+
raise GithubAPIError(response.status)
441452
cache[page] = await response.json()
442453
return cache[page]
443454

@@ -462,7 +473,7 @@ async def get_stars_gained(self, repo: str, start: str, end: str) -> int:
462473

463474
repo_data, response = await self.fetch_data(f"{GITHUB_API_URL}/repos/{repo}")
464475
if response.status != 200:
465-
return -1
476+
raise GithubAPIError(response.status)
466477

467478
max_stars = repo_data.get("stargazers_count", 0)
468479

@@ -473,7 +484,7 @@ async def get_stars_gained(self, repo: str, start: str, end: str) -> int:
473484
# Because of this the output is not consistent for projects with more than 40 000 stars so we default to -2
474485
github_stargazer_limit = 40000
475486
if max_stars > github_stargazer_limit:
476-
return -2
487+
raise StargazersLimitError("Repository exceeds the 40,000 star limit.")
477488
searchable_stars = max_stars
478489

479490
# We use a cache and binary search to limit the number of requests to the GitHub API
@@ -566,7 +577,7 @@ async def github_stats(self, ctx: commands.Context, start: str, end: str, repo:
566577
return
567578

568579
url = f"{GITHUB_API_URL}/repos/{repo}"
569-
repo_data, response = await self.fetch_data(url)
580+
repo_data, _ = await self.fetch_data(url)
570581

571582
if "message" in repo_data:
572583
embed = discord.Embed(
@@ -577,22 +588,28 @@ async def github_stats(self, ctx: commands.Context, start: str, end: str, repo:
577588
await ctx.send(embed=embed)
578589
return
579590

580-
open_issues = await self.get_issue_count(repo, start, end, state="created")
581-
closed_issues = await self.get_issue_count(repo, start, end, state="closed")
582-
prs_opened = await self.get_pr_count(repo, start, end, "opened")
583-
prs_closed = await self.get_pr_count(repo, start, end, "closed")
584-
prs_merged = await self.get_pr_count(repo, start, end, "merged")
585-
commits = await self.get_commit_count(repo, start, end)
586-
stars_gained = await self.get_stars_gained(repo, start, end)
587-
588-
if stars_gained == -2:
589-
stars = "N/A (repo exceeds API limit)"
590-
elif stars_gained > 0:
591-
stars = f"+{stars_gained}"
592-
elif stars_gained == 0:
593-
stars = "0"
594-
else:
595-
stars = "unavailable"
591+
try:
592+
open_issues = await self.get_issue_count(repo, start, end, state="created")
593+
closed_issues = await self.get_issue_count(repo, start, end, state="closed")
594+
prs_opened = await self.get_pr_count(repo, start, end, "opened")
595+
prs_closed = await self.get_pr_count(repo, start, end, "closed")
596+
prs_merged = await self.get_pr_count(repo, start, end, "merged")
597+
commits = await self.get_commit_count(repo, start, end)
598+
599+
try:
600+
stars_gained = await self.get_stars_gained(repo, start, end)
601+
stars = f"+{stars_gained}" if stars_gained > 0 else "0"
602+
except StargazersLimitError:
603+
stars = "N/A (repo exceeded API limit)"
604+
605+
except GithubAPIError as e:
606+
embed = discord.Embed(
607+
title=random.choice(NEGATIVE_REPLIES),
608+
description=f"Failed to fetch data from GitHub API. (Status Code: {e.status})",
609+
colour=Colours.soft_red,
610+
)
611+
await ctx.send(embed=embed)
612+
return
596613

597614
stats_text = (
598615
f"Issues opened: {open_issues}\n"

0 commit comments

Comments
 (0)