refactor: drop dead query helpers and simplify read deadline (WealthLedger/frontend#141) (#149)
Frontend verify / commits (push) Skipped
Frontend verify / security (push) Successful in 11s
Frontend verify / verify (push) Failing after 7m35s

This commit was merged in pull request #149.
This commit is contained in:
2026-11-04 18:50:27 +03:00
parent e2d143df46
commit 5077bd4f0b
5 changed files with 72 additions and 229 deletions
+27 -28
View File
@@ -208,51 +208,50 @@ function parseJson(body: string): unknown {
}
async function readAttempt(request: Request): Promise<ReadAttempt> {
const controller = new AbortController();
const failure: { reason?: "abort" | "timeout" } = {};
const { promise: deadline, reject: rejectDeadline }
= Promise.withResolvers<never>();
const timeout = setTimeout(() => {
failure.reason = "timeout";
controller.abort();
rejectDeadline(abortError());
}, GET_DEADLINE_MS);
const abort = () => {
failure.reason = "abort";
controller.abort();
rejectDeadline(abortError());
};
request.signal.addEventListener("abort", abort, { once: true });
const timedRequest = new Request(request, { signal: controller.signal });
// Manual timeout (not AbortSignal.timeout) so fake-timer tests can advance it.
const timeout = new AbortController();
const timer = setTimeout(() => timeout.abort(), GET_DEADLINE_MS);
const signal = AbortSignal.any([request.signal, timeout.signal]);
try {
const response = await Promise.race([fetch(timedRequest), deadline]);
const body = await Promise.race([response.text(), deadline]);
const problem = parseJson(body);
// MSW keeps a stalled body readable after abort, so keep the race.
const response = await Promise.race([
fetch(new Request(request, { signal })),
rejectOnAbort(signal),
]);
const body = await Promise.race([response.text(), rejectOnAbort(signal)]);
return {
problem,
problem: parseJson(body),
reason: "transient",
response: new Response(body, response),
};
}
catch (error) {
if (failure.reason === "abort") return { reason: "abort" };
if (failure.reason === "timeout" || isNetworkFailure(error))
if (request.signal.aborted) return { reason: "abort" };
// Timeout or network failure: retryable.
if (timeout.signal.aborted || isNetworkFailure(error))
return { reason: "transient" };
throw error;
}
finally {
clearTimeout(timeout);
request.signal.removeEventListener("abort", abort);
clearTimeout(timer);
}
}
function rejectOnAbort(signal: AbortSignal): Promise<never> {
return new Promise((_resolve, reject) => {
// The signal is either already aborted or one of two parents firing once.
signal.addEventListener(
"abort",
() => reject(abortError()),
{ once: true },
);
});
}
function retryAfterMs(response: Response): number | undefined {
const header = response.headers.get("Retry-After");
if (!header) return undefined;