Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix timeout error firing even though it's cancelled #2399

Merged
merged 12 commits into from
Feb 10, 2025
10 changes: 9 additions & 1 deletion source/core/timed-out.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ export default function timedOut(request: ClientRequest, delays: Delays, options
request[reentry] = true;
const cancelers: Array<typeof noop> = [];
const {once, unhandleAll} = unhandler();
const handled: Map<string, boolean> = new Map<string, boolean>();

const addTimeout = (delay: number, callback: (delay: number, event: string) => void, event: string): (typeof noop) => {
const timeout = setTimeout(callback, delay, delay, event) as unknown as NodeJS.Timeout;

timeout.unref?.();

const cancel = (): void => {
handled.set(event, true);
clearTimeout(timeout);
};

Expand All @@ -69,7 +71,13 @@ export default function timedOut(request: ClientRequest, delays: Delays, options
const {host, hostname} = options;

const timeoutHandler = (delay: number, event: string): void => {
request.destroy(new TimeoutError(delay, event));
// Use queueMicroTask to allow for any cancelled events to be handled first,
// to prevent firing any TimeoutError unneeded when the event loop is busy or blocked
queueMicrotask(() => {
paulrutter marked this conversation as resolved.
Show resolved Hide resolved
if (!handled.has(event)) {
request.destroy(new TimeoutError(delay, event));
}
});
};

const cancelTimeouts = (): void => {
Expand Down
Loading