fix(frontend api adapter): use abortcontroller.abort when abortsignal.timeout is not available (@miodec) (#5714)

* setTimeout approach

* better approach

* remove console log

* better polyfill check
This commit is contained in:
Jack 2024-08-02 10:57:43 +02:00 committed by GitHub
parent b22e0a407d
commit fe50fe1659
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -5,6 +5,12 @@ import { envConfig } from "../../constants/env-config";
import { getAuthenticatedUser, isAuthenticated } from "../../firebase";
import { EndpointMetadata } from "@monkeytype/contracts/schemas/api";
function timeoutSignal(ms: number): AbortSignal {
const ctrl = new AbortController();
setTimeout(() => ctrl.abort(new Error("request timed out")), ms);
return ctrl.signal;
}
function buildApi(timeout: number): (args: ApiFetcherArgs) => Promise<{
status: number;
body: unknown;
@ -27,12 +33,22 @@ function buildApi(timeout: number): (args: ApiFetcherArgs) => Promise<{
headers["Authorization"] = `Bearer ${token}`;
}
const response = await fetch(request.path, {
signal: AbortSignal?.timeout?.(timeout),
const fetchOptions: RequestInit = {
method: request.method as Method,
headers,
body: request.body,
};
const usePolyfill = AbortSignal?.timeout === undefined;
const response = await fetch(request.path, {
...fetchOptions,
signal: usePolyfill
? timeoutSignal(timeout)
: AbortSignal.timeout(timeout),
});
const body = await response.json();
if (response.status >= 400) {
console.error(`${request.method} ${request.path} failed`, {
@ -47,9 +63,19 @@ function buildApi(timeout: number): (args: ApiFetcherArgs) => Promise<{
headers: response.headers ?? new Headers(),
};
} catch (e: Error | unknown) {
let message = "Unknown error";
if (e instanceof Error) {
if (e.message.includes("timed out")) {
message = "request took too long to complete";
} else {
message = e.message;
}
}
return {
status: 500,
body: { message: e },
body: { message },
headers: new Headers(),
};
}