Skip to content

Commit 8c51fb6

Browse files
committed
feat: add timeout to getApiResponse
1 parent 6fa936c commit 8c51fb6

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/utils/shared/get-api-response.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,48 @@
11
import { IS_PROD } from '@/constants';
22
import { consoleLog } from '@/utils/shared/console-log';
33

4+
/**
5+
* Makes an API request and returns the response data.
6+
*
7+
* @param apiEndpoint - The API endpoint URL.
8+
* @param requestData - The request data to be sent in the request body.
9+
* @param method - The HTTP method for the request (default: 'GET').
10+
* @param revalidate - The time in seconds to cache the data (default: 3600 seconds in production, 120 seconds otherwise).
11+
* @param headers - The headers to be included in the request.
12+
* @param timeout - The timeout in milliseconds for the request (default: 100000 = 100 seconds).
13+
* @returns The response data from the API.
14+
* @throws An error if the API request fails or times out.
15+
*/
416
export const getApiResponse = async <T>({
517
apiEndpoint,
618
requestData,
719
method = 'GET',
820
revalidate = IS_PROD ? 3600 : 120, // cache data in seconds
921
headers,
22+
timeout = 100000, // 100 seconds
1023
}: {
1124
apiEndpoint: string;
1225
requestData?: BodyInit;
1326
method?: 'POST' | 'GET' | 'PUT' | 'DELETE';
1427
revalidate?: number;
1528
headers?: HeadersInit;
29+
timeout?: number;
1630
}) => {
1731
try {
1832
const startTime = Date.now();
33+
const controller = new AbortController();
34+
const signal = controller.signal;
35+
36+
const timeoutId = setTimeout(() => controller.abort(), timeout);
37+
1938
const response = await fetch(apiEndpoint, {
2039
method,
2140
body: requestData,
2241
headers,
2342
next: {
2443
revalidate,
2544
},
45+
signal,
2646
});
2747
if (!response.ok) {
2848
consoleLog('🚀 Debug getApiResponse requestData:', requestData);
@@ -38,9 +58,18 @@ export const getApiResponse = async <T>({
3858
duration > 2000 ? '💔' : '-'
3959
} ${apiEndpoint}`
4060
);
41-
61+
clearTimeout(timeoutId);
62+
// if is not valid JSON, return response
63+
if (!response.headers.get('content-type')?.includes('application/json')) {
64+
return response as T;
65+
}
4266
return (await response.json()) as T;
4367
} catch (error) {
68+
if (error instanceof Error && error.name === 'AbortError') {
69+
throw new Error(
70+
'Fetch request timed out: ' + (timeout / 1000).toFixed(1) + ' s'
71+
);
72+
}
4473
consoleLog('getApiResponse error:', error);
4574
}
4675

0 commit comments

Comments
 (0)