bun/prefer-timeout-signal
Prefer AbortSignal.timeout() to an AbortController that only a timer aborts
AbortSignal.timeout(ms) replaces an AbortController and the setTimeout that aborts it with one call. Its signal also aborts with a TimeoutError instead of an AbortError, so the code that catches the error can tell a timeout from a cancellation.
A controller is reported if one setTimeout(() => controller.abort(), ms) is the only thing that aborts it, and the rest of the code only reads controller.signal.
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"bun/prefer-timeout-signal" = "error" # or "warn"Every option, set to its default:
bunfig.toml
[lint.rules]
"bun/prefer-timeout-signal" = ["error", {
factories = [], # list of strings
}]Examples#
example.js1 problem
const controller = new AbortController()Only a timer aborts this controller. Use AbortSignal.timeout(ms) instead.;
setTimeout(() => controller.abort(), 5000);
const response = await fetch(url, { signal: controller.signal });example.jsNo problems
const response = await fetch(url, { signal: AbortSignal.timeout(5000) });A controller that something else can also abort isn't reported:
example.jsNo problems
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);
cancelButton.addEventListener("click", () => controller.abort());
const response = await fetch(url, { signal: controller.signal });Neither is one that aborts with its own reason:
example.jsNo problems
const controller = new AbortController();
setTimeout(() => controller.abort(new Error("The upload took too long")), 5000);
await upload(file, { signal: controller.signal });Options#
| Option | Default | What it does |
|---|---|---|
factories | [] | Names of your own functions that return an AbortController. Their return value is checked like new AbortController(). |
example.jswith
{ "factories": ["createController"] }1 problemconst controller = createController()Only a timer aborts this controller. Use AbortSignal.timeout(ms) instead.;
setTimeout(() => controller.abort(), 5000);
const response = await fetch(url, { signal: controller.signal });