fix(planner/brouter): add 30s timeout to outbound fetch
Mirrors journal PR #5. `fetchSegment()` and `computeSegmentGpx()` in lib/brouter.ts called `fetch()` with no AbortSignal — a hung or slow BRouter would stall the request handler indefinitely. New `lib/http.server.ts::fetchWithTimeout()` (same as the journal's helper) wraps fetch with `AbortSignal.timeout(30_000)`, composable with a caller-supplied signal via `AbortSignal.any()`. Tests: lib/http.server.test.ts (2 cases — timeout abort, happy path).
This commit is contained in:
parent
e647a29633
commit
d70d6ee8a8
3 changed files with 46 additions and 2 deletions
28
apps/planner/app/lib/http.server.test.ts
Normal file
28
apps/planner/app/lib/http.server.test.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import { describe, it, expect, vi, afterEach } from "vitest";
|
||||
import { fetchWithTimeout } from "./http.server.ts";
|
||||
|
||||
const originalFetch = globalThis.fetch;
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.fetch = originalFetch;
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("fetchWithTimeout (planner)", () => {
|
||||
it("aborts when the upstream exceeds the timeout", async () => {
|
||||
globalThis.fetch = vi.fn((_input: RequestInfo | URL, init?: RequestInit) => {
|
||||
return new Promise((_resolve, reject) => {
|
||||
init?.signal?.addEventListener("abort", () => {
|
||||
reject(new DOMException("aborted", "AbortError"));
|
||||
});
|
||||
});
|
||||
}) as typeof fetch;
|
||||
await expect(fetchWithTimeout("https://example.test", {}, 25)).rejects.toThrow();
|
||||
});
|
||||
|
||||
it("returns the response when the call resolves in time", async () => {
|
||||
globalThis.fetch = vi.fn(async () => new Response("ok", { status: 200 })) as typeof fetch;
|
||||
const resp = await fetchWithTimeout("https://example.test", {}, 1000);
|
||||
expect(resp.status).toBe(200);
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue