diff --git a/frontend/islands/GithubUserLink.tsx b/frontend/islands/GithubUserLink.tsx
index 250238fb..da407582 100644
--- a/frontend/islands/GithubUserLink.tsx
+++ b/frontend/islands/GithubUserLink.tsx
@@ -6,6 +6,7 @@ import { cachedGitHubLogin } from "../utils/github.ts";
export function GitHubUserLink({ user }: { user?: User }) {
const login = useSignal("");
+ const error = useSignal(false);
useEffect(() => {
if (user) {
@@ -13,10 +14,20 @@ export function GitHubUserLink({ user }: { user?: User }) {
.then((login_) => {
login.value = login_;
})
- .catch(console.error);
+ .catch((error_) => {
+ console.error(error_);
+
+ error.value = true;
+ });
}
});
+ if (error.value) {
+ return (
+ Could not load GitHub username
+ );
+ }
+
return login.value == ""
? loading...
: GitHub;
diff --git a/frontend/utils/github.ts b/frontend/utils/github.ts
index 3ea14d65..f48e223d 100644
--- a/frontend/utils/github.ts
+++ b/frontend/utils/github.ts
@@ -5,15 +5,41 @@ import { getOrInsertItem } from "./client_cache.ts";
export async function cachedGitHubLogin(user: User): Promise {
return await getOrInsertItem(
`gh-login-${user.githubId}`,
- () =>
- fetch(`https://api.github.com/user/${user.githubId}`, {
- headers: {
- "Content-Type": "application/json",
- },
- })
- .then((r) => r.json())
- .then((data) => {
- return data.login;
- }),
+ () => {
+ const MAX_RETRIES = 3;
+ const fetchGithubUser = async (retryCount = 0) => {
+ const response = await fetch(
+ `https://api.github.com/user/${user.githubId}`,
+ {
+ headers: {
+ "Content-Type": "application/json",
+ },
+ },
+ );
+
+ if (
+ response.status === 403 &&
+ response.headers.get("x-ratelimit-remaining") === "0"
+ ) {
+ throw new Error("Github API rate limit exceeded");
+ }
+
+ const data = await response.json();
+
+ if (!data.login) {
+ if (retryCount >= MAX_RETRIES) {
+ throw new Error(
+ "Failed to fetch GitHub login after maximum retries",
+ );
+ }
+
+ await new Promise((resolve) => setTimeout(resolve, 100));
+ return fetchGithubUser(retryCount + 1);
+ }
+ return data.login;
+ };
+
+ return fetchGithubUser();
+ },
);
}