Summary
require-async-entrypoint-catch (the newest rule) only detects module-scope async FunctionDeclarations and only flags a bare Identifier() ExpressionStatement. Two common entrypoint shapes silently escape the rule, producing false negatives for exactly the unhandled-rejection class the rule exists to catch.
Gap 1 — async function expressions / arrow functions assigned at module scope
The collector only handles FunctionDeclaration:
FunctionDeclaration(node) {
if (node.async && node.id?.name && node.parent.type === AST_NODE_TYPES.Program) {
asyncFunctionNames.add(node.id.name);
}
},
So these equivalent entrypoints are never tracked and their bare calls are never flagged:
const main = async () => { /* ... */ };
main(); // FN: unhandled rejection, not flagged
const run = async function () { /* ... */ };
if (require.main === module) run(); // FN
The rule's own test suite documents this boundary (only FunctionDeclaration cases are covered; const main = async () => {} appears only in a valid/await case).
Gap 2 — .then() chained without a .catch()
The call handler bails whenever the callee is not a plain Identifier, so a .then() chain with no rejection handler is treated as "handled":
main().then(() => process.exit(0)); // FN: rejection still unhandled
(A chain that does end in .catch(...) should remain valid, as it is today.)
Grounding / severity
Current live actions/setup/js entrypoints are all either sync function main() (correctly ignored) or async FunctionDeclarations that the rule already catches (e.g. parse_mcp_scripts_logs.cjs:415, parse_token_usage.cjs:238 — true positives). Arrow/expression async entrypoints presently appear only as await-guarded helpers, so this is a preventive robustness/parity refinement: the sibling error-property rules were hardened for computed/aliased forms for the same reason, and detection here should not depend on the author's choice of declaration syntax.
Acceptance criteria
See also #42189 / #42915 (branch-order guard FNs in the sibling catch-error-property rules) — same theme of tightening the newest error-handling rules against real-world variance.
Generated by 🤖 ESLint Refiner · 147.1 AIC · ⌖ 12.9 AIC · ⊞ 4.7K · ◷
Summary
require-async-entrypoint-catch(the newest rule) only detects module-scope asyncFunctionDeclarations and only flags a bareIdentifier()ExpressionStatement. Two common entrypoint shapes silently escape the rule, producing false negatives for exactly the unhandled-rejection class the rule exists to catch.Gap 1 — async function expressions / arrow functions assigned at module scope
The collector only handles
FunctionDeclaration:So these equivalent entrypoints are never tracked and their bare calls are never flagged:
The rule's own test suite documents this boundary (only
FunctionDeclarationcases are covered;const main = async () => {}appears only in a valid/await case).Gap 2 —
.then()chained without a.catch()The call handler bails whenever the callee is not a plain
Identifier, so a.then()chain with no rejection handler is treated as "handled":(A chain that does end in
.catch(...)should remain valid, as it is today.)Grounding / severity
Current live
actions/setup/jsentrypoints are all either syncfunction main()(correctly ignored) or asyncFunctionDeclarations that the rule already catches (e.g.parse_mcp_scripts_logs.cjs:415,parse_token_usage.cjs:238— true positives). Arrow/expression async entrypoints presently appear only as await-guarded helpers, so this is a preventive robustness/parity refinement: the sibling error-property rules were hardened for computed/aliased forms for the same reason, and detection here should not depend on the author's choice of declaration syntax.Acceptance criteria
const/let/var X = async function () {}andconst/let/var X = async () => {}(VariableDeclarator with an async init), in addition toFunctionDeclaration.X()ExpressionStatement for such tracked names, with the existing.catch(...)suggestion fix.X().then(...)ExpressionStatements that do not terminate in a.catch(...); keep chains ending in.catch(...)valid..catchpresent, awaited inside async, sync arrow) and invalid (bare arrow/fn-expr call,.then()without catch) with expected suggestion output.actions/setup/js/**/*.cjscorpus.See also #42189 / #42915 (branch-order guard FNs in the sibling catch-error-property rules) — same theme of tightening the newest error-handling rules against real-world variance.