bun/no-unbounded-requests

Require an axios request to have a timeout or a signal

By default axios has no timeout. If the server accepts the connection and never answers, the promise never settles, and anything that awaits it hangs. Set timeout, or pass a signal that ends the request.

The rule looks at axios(), axios.request(), axios.create(), and methods such as axios.get() and axios.post(). A timeout of 0 or Infinity is reported too, because it sets no limit.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"bun/no-unbounded-requests" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"bun/no-unbounded-requests" = ["error", {
  clients = [], # list of objects
}]

Examples#

example.js3 problems
import axios from "axios";

const user = await axios.get(`/users/${id}`);
await axios.post("/users", user, { headers });
const api = axios.create({ baseURL: "https://api.example.com", timeout: 0 });
example.jsNo problems
import axios from "axios";

const user = await axios.get(`/users/${id}`, { timeout: 5000 });
await axios.post("/users", user, { headers, signal: AbortSignal.timeout(5000) });
const api = axios.create({ baseURL: "https://api.example.com", timeout: 5000 });

A file that sets a default timeout isn't checked:

example.jsNo problems
import axios from "axios";

axios.defaults.timeout = 5000;

const user = await axios.get(`/users/${id}`);

A config with cancelToken passes too. A config that's a variable, or that spreads another object, isn't checked, because the rule can't see what's in it. For an instance, the axios.create() call is checked and the requests made with it aren't.

example.jsNo problems
import axios from "axios";

await axios.get("/users", requestConfig);
await axios.get("/users", { ...requestConfig, params });

const api = axios.create({ timeout: 5000 });
await api.get("/users");

Options#

OptionDefaultWhat it does
clients[]More modules that export something you call like axios. Each entry is { module, names }, with the import specifier and the export names. Without names, the default export is the client.
bunfig.toml
[lint.rules]
"bun/no-unbounded-requests" = ["error", {
  clients = [{ module = "./http.js", names = ["api"] }],
}]
example.jswith { "clients": [{ "module": "./http.js", "names": ["api"] }] }1 problem
import { api } from "./http.js";

const users = await api.get("/users");
example.jswith { "clients": [{ "module": "./http.js" }] }1 problem
import api from "./http.js";

const users = await api.get("/users");