68 lines
1.6 KiB
TypeScript
68 lines
1.6 KiB
TypeScript
import uwuzuError from "./error";
|
|
|
|
export function generateURL(
|
|
origin: string,
|
|
endpoint: string,
|
|
) {
|
|
const uri = new URL(`/api/${endpoint}`, origin);
|
|
return uri.toString();
|
|
}
|
|
|
|
export default async function uwuzuFetch(
|
|
origin: string,
|
|
retryCount: number,
|
|
waitingTime: number,
|
|
inputType: "endpoint" | "other",
|
|
input: string,
|
|
init?: RequestInit,
|
|
) {
|
|
const waiting = (ms: number) =>
|
|
new Promise<void>(resolve => setTimeout(resolve, ms));
|
|
|
|
if (inputType === "endpoint")
|
|
input = generateURL(origin, input);
|
|
|
|
let lastError;
|
|
|
|
for (let i = 0; i < retryCount; i++) {
|
|
try {
|
|
if (init?.signal?.aborted) {
|
|
throw new DOMException("Aborted", "AbortError");
|
|
}
|
|
|
|
const req = await fetch(input, init);
|
|
|
|
if (
|
|
Math.floor(req.status / 200) === 1 ||
|
|
Math.floor(req.status / 300) === 1
|
|
) {
|
|
return req;
|
|
}
|
|
|
|
if (Math.floor(req.status / 400) === 1)
|
|
throw new uwuzuError(`Client error: HTTP${req.status} - ${req.statusText}`);
|
|
|
|
lastError = new Error(`Request failed: HTTP${req.status} - ${req.statusText}`);
|
|
} catch (err) {
|
|
if (err instanceof DOMException && err.name === "AbortError") {
|
|
throw err;
|
|
}
|
|
|
|
if (
|
|
err instanceof uwuzuError &&
|
|
err.name === "Client error" &&
|
|
err.message.startsWith("HTTP4")
|
|
)
|
|
throw err;
|
|
|
|
lastError = err;
|
|
}
|
|
|
|
if (i < retryCount - 1) {
|
|
const waitTime = waitingTime * 2 ** i;
|
|
await waiting(waitTime);
|
|
}
|
|
}
|
|
|
|
throw lastError ?? new Error("Unknown Error");
|
|
} |