# 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`.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"bun/prefer-timeout-signal" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"bun/prefer-timeout-signal" = ["error", {
  factories = [], # list of strings
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```js
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

const response = await fetch(url, { signal: controller.signal });
```

Not reported:

{/* good */}
```js
const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
```

A controller that something else can also abort isn't reported:

{/* good */}
```js
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:

{/* good */}
```js
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()`. |

{/* bad {"options": [{"factories": ["createController"]}]} */}
```js
const controller = createController();
setTimeout(() => controller.abort(), 5000);

const response = await fetch(url, { signal: controller.signal });
```
