Skip to content

Commit ffc839a

Browse files
refactor: simplify API fetch error handling in aa-chains route
1 parent 0e26a88 commit ffc839a

File tree

2 files changed

+29
-26
lines changed

2 files changed

+29
-26
lines changed
Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { NextResponse } from "next/server";
2-
import type { ChainMetadata } from "thirdweb/chains";
2+
import { defineChain, getChainMetadata } from "thirdweb/chains";
33

44
export const maxDuration = 300; // max timeout 300 seconds (5min)
55
export const revalidate = 86400; // Revalidate every 24 hours (86400 seconds)
@@ -9,28 +9,14 @@ type ApiResponseType = {
99
};
1010

1111
export async function GET() {
12-
const [chainsWithServices, allChains] = await Promise.all([
13-
fetch("https://api.thirdweb.com/v1/chains/services", {
12+
const chainsWithServices = await fetch(
13+
"https://api.thirdweb.com/v1/chains/services",
14+
{
1415
headers: {
1516
"Content-Type": "application/json",
1617
},
17-
})
18-
.then((res) => res.json() as Promise<ApiResponseType>)
19-
.catch((error) => {
20-
console.error(error);
21-
return { data: {} as ApiResponseType["data"] };
22-
}),
23-
fetch("https://api.thirdweb.com/v1/chains", {
24-
headers: {
25-
"Content-Type": "application/json",
26-
},
27-
})
28-
.then((res) => res.json() as Promise<{ data: ChainMetadata[] }>)
29-
.catch((error) => {
30-
console.error(error);
31-
return { data: [] as ChainMetadata[] };
32-
}),
33-
]);
18+
},
19+
).then((res) => res.json() as Promise<ApiResponseType>);
3420

3521
const aaChains = Object.entries(chainsWithServices.data)
3622
.filter(([, services]) =>
@@ -41,14 +27,30 @@ export async function GET() {
4127
)
4228
.map(([chainId]) => Number(chainId));
4329

44-
const intersectedChains = allChains.data
45-
.filter((chain) =>
46-
aaChains.some((aaChainId) => aaChainId === chain.chainId),
47-
)
30+
const chunkSize = 5;
31+
// dont fetch all chains at once to avoid rate limiting
32+
const allChains = await Promise.all(
33+
Array.from(
34+
{ length: Math.ceil(aaChains.length / chunkSize) },
35+
async (_, i) => {
36+
if (i > 0) {
37+
await new Promise((resolve) => setTimeout(resolve, 300));
38+
}
39+
return Promise.all(
40+
aaChains
41+
.slice(i * chunkSize, (i + 1) * chunkSize)
42+
.map((id) => getChainMetadata(defineChain({ id }))),
43+
);
44+
},
45+
),
46+
);
47+
48+
const cleanedUpChains = allChains
49+
.flat()
4850
.filter((c) => c.name)
4951
.sort((a, b) => a.name.localeCompare(b.name));
5052

5153
return NextResponse.json({
52-
data: intersectedChains,
54+
data: cleanedUpChains,
5355
});
5456
}

apps/portal/src/components/Document/AAChainList.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ async function getChains(): Promise<ChainMetadata[]> {
77
try {
88
const chains = await fetch(`${getBaseUrl()}/api/aa-chains`);
99
if (!chains.ok) {
10+
console.error("Failed to fetch chains", chains.statusText);
1011
return [];
1112
}
1213
const result = (await chains.json()) as { data: ChainMetadata[] };
1314
return result.data;
1415
} catch (error) {
15-
console.error(error);
16+
console.error("Failed to fetch chains", error);
1617
return [];
1718
}
1819
}

0 commit comments

Comments
 (0)