oxc/no-async-endpoint-handlers
Disallow async functions as Express route handlers and middleware
Express 4 ignores the promise that an async handler returns. If the handler throws, or awaits something that rejects, your error middleware never runs. The request hangs, and the unhandled rejection can crash the process.
The rule checks .get(), .post(), .put(), .patch(), .delete(), .head(), .options(), .all(), and .use() on any object. A function written in the call is only reported if its parameters have the usual names, such as (req, res) or (err, req, res, next). A handler passed by name is looked up in the same file.
Configure#
Off by default. To turn it on:
[lint.rules]
"oxc/no-async-endpoint-handlers" = "error" # or "warn"Every option, set to its default:
[lint.rules]
"oxc/no-async-endpoint-handlers" = ["error", {
allowedNames = [], # list of strings
}]Examples#
app.get("/users/:id", asyncExpress endpoint handler for /users/:id should not be async. (req, res) => {
const user = await db.findUser(req.params.id);
res.json(user);
});asyncExpress endpoint handler for /users should not be async. function listUsers(req, res) {
res.json(await db.allUsers());
}
router.get("/users", listUsers);app.get("/users/:id", (req, res, next) => {
db.findUser(req.params.id)
.then(user => res.json(user))
.catch(next);
});A handler wrapped in a call isn't reported, so a helper that passes rejections to next works too:
const wrap = handler => (req, res, next) => handler(req, res, next).catch(next);
app.get(
"/users/:id",
wrap(async (req, res) => {
res.json(await db.findUser(req.params.id));
}),
);Options#
| Option | Default | What it does |
|---|---|---|
allowedNames | [] | Names of async functions you can use as handlers. |
{ "allowedNames": ["listUsers"] }No problemsasync function listUsers(req, res) {
res.json(await db.allUsers());
}
router.get("/users", listUsers);The name is the function's own name. An arrow function doesn't have one, so it's reported even if the variable that holds it is in the list:
{ "allowedNames": ["listUsers"] }1 problemconst listUsers = asyncExpress endpoint handler for /users should not be async. (req, res) => {
res.json(await db.allUsers());
};
router.get("/users", listUsers);When not to use it#
Express 5 passes a rejected promise to next by itself, so async handlers are safe there.