mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 16:38:27 +00:00
fix(infra): avoid detached finally unhandled rejection in fetch wrapper (#18014)
Merged via /review-pr -> /prepare-pr -> /merge-pr.
Prepared head SHA: 4ec21c89cb
Co-authored-by: Jackten <2895479+Jackten@users.noreply.github.com>
Co-authored-by: sebslight <19554889+sebslight@users.noreply.github.com>
Reviewed-by: @sebslight
This commit is contained in:
@@ -45,18 +45,32 @@ export function wrapFetchWithAbortSignal(fetchImpl: typeof fetch): typeof fetch
|
||||
}
|
||||
const controller = new AbortController();
|
||||
const onAbort = bindAbortRelay(controller);
|
||||
let listenerAttached = false;
|
||||
if (signal.aborted) {
|
||||
controller.abort();
|
||||
} else {
|
||||
signal.addEventListener("abort", onAbort, { once: true });
|
||||
listenerAttached = true;
|
||||
}
|
||||
const response = fetchImpl(input, { ...patchedInit, signal: controller.signal });
|
||||
if (typeof signal.removeEventListener === "function") {
|
||||
void response.finally(() => {
|
||||
const cleanup = () => {
|
||||
if (!listenerAttached || typeof signal.removeEventListener !== "function") {
|
||||
return;
|
||||
}
|
||||
listenerAttached = false;
|
||||
try {
|
||||
signal.removeEventListener("abort", onAbort);
|
||||
});
|
||||
} catch {
|
||||
// Foreign/custom AbortSignal implementations may throw here.
|
||||
// Never let cleanup mask the original fetch result/error.
|
||||
}
|
||||
};
|
||||
try {
|
||||
const response = fetchImpl(input, { ...patchedInit, signal: controller.signal });
|
||||
return response.finally(cleanup);
|
||||
} catch (error) {
|
||||
cleanup();
|
||||
throw error;
|
||||
}
|
||||
return response;
|
||||
}) as FetchWithPreconnect;
|
||||
|
||||
const fetchWithPreconnect = fetchImpl as FetchWithPreconnect;
|
||||
|
||||
Reference in New Issue
Block a user