Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions src/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,20 +167,26 @@ export function createFetch(globalOptions: CreateFetchOptions = {}): $Fetch {
}

let abortTimeout: NodeJS.Timeout | undefined;
let fetchOptions = context.options;

// The timeout signal is derived per attempt: reusing it across retries
// would forward an already aborted signal.
if (context.options.timeout) {
context.options.signal = context.options.signal
? AbortSignal.any([
AbortSignal.timeout(context.options.timeout),
context.options.signal,
])
: AbortSignal.timeout(context.options.timeout);
fetchOptions = {
...context.options,
signal: context.options.signal
? AbortSignal.any([
AbortSignal.timeout(context.options.timeout),
context.options.signal,
])
: AbortSignal.timeout(context.options.timeout),
};
}

try {
context.response = await fetch(
context.request,
context.options as RequestInit
fetchOptions as RequestInit
);
} catch (error) {
context.error = error as Error;
Expand Down
20 changes: 20 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { $fetch } from "../src/index.ts";

describe("ofetch", () => {
let listener: ReturnType<typeof serve>;
let timeoutOnceRequests = 0;
const getURL = (url: string = "/") =>
listener.url! + (url.replace(/^\//, "") || "");

Expand Down Expand Up @@ -62,6 +63,15 @@ describe("ofetch", () => {
resolve(new HTTPError({ status: 408 }));
}, 1000 * 5);
});
})
.all("/timeout-once", async () => {
timeoutOnceRequests++;
if (timeoutOnceRequests === 1) {
await new Promise((resolve) => {
setTimeout(resolve, 1000 * 5);
});
}
return "ok";
});

listener = await serve(app, { port: 0, hostname: "localhost" }).ready();
Expand Down Expand Up @@ -344,6 +354,16 @@ describe("ofetch", () => {
});
});

it("retrying after a timeout", async () => {
const result = await $fetch<string>(getURL("timeout-once"), {
timeout: 100,
retry: 1,
});

expect(result).to.equal("ok");
expect(timeoutOnceRequests).to.equal(2);
});

it("deep merges defaultOptions", async () => {
const _customFetch = $fetch.create({
query: {
Expand Down