fix: fall back to WHOIS when a bootstrap fetch aborts on its own

Any AbortError from the bootstrap fetch was rethrown, so a customFetch's own
timeout ended the whole lookup as "aborted" (documented as "your own signal
fired") with no WHOIS fallback; the same error during the RDAP domain fetch
already fell back. Caller aborts and deadlines are still rethrown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jakeandClaude Opus 5.5 committed 2026-10-03 15:34:51 -04:00
1 parent 3b97803720
commit 7a39bc3bfa
2 files changed
+21 -3

No files matched your search

+18
View File
@@ -342,3 +342,21 @@ describe("timeouts, deadline and abort", () => {
expect(vi.mocked(whoisQuery)).not.toHaveBeenCalled();
});
});
describe("bootstrap AbortError not caused by the caller", () => {
it("falls back to WHOIS instead of failing as aborted", async () => {
vi.mocked(whoisQuery).mockResolvedValue({
serverQueried: "whois.verisign-grs.com",
text: whoisText,
});
const customFetch: FetchLike = vi.fn(async () => {
throw new DOMException("customFetch timed out", "AbortError");
});
const res = await lookup("example.com", {
customFetch,
whoisHints: { com: "whois.verisign-grs.com" },
});
expect(res.ok, res.error).toBe(true);
expect(res.record?.source).toBe("whois");
});
});
+3 -3
View File
@@ -76,12 +76,12 @@ async function loadBootstrapData(
},
),
);
} catch (err: unknown) {
} catch {
// Preserve caller cancellation behavior - rethrow if explicitly aborted (or deadline hit)
if (options?.signal?.aborted) throwIfAborted(options.signal);
if (err instanceof Error && err.name === "AbortError") throw err;
// Network, timeout, or JSON parse errors - return empty array to fall back to WHOIS
// (the failure is recorded in ctx.attempts)
// (the failure is recorded in ctx.attempts). An AbortError the caller didn't cause (a
// customFetch's own timeout) is one of these.
return undefined;
}
}