Summary
Add a detector for floating/unawaited promises — async calls whose returned promise is neither awaited, returned, nor .catch-handled — including fire-and-forget async work started inside React effects.
Motivation
Unawaited promises cause silent failures, race conditions, and unhandled rejections. They are easy to introduce when editing quickly and are not covered by any current rule. This pairs naturally with effect-complexity for the React case.
Proposed behavior
floating-promise: a call to a function known/inferred to return a promise (async function, .then-able, or common APIs like fetch) used as an expression statement without await, return, void, or .catch(...).
- React-aware variant: async work kicked off inside
useEffect without cleanup/handling.
- Conservative defaults to keep false positives low (only flag clearly promise-returning calls; allow
void expr as an explicit opt-out, matching common lint conventions).
Implementation surface
- New
src/detectors/floatingPromise.ts using ts-morph type/heuristic inference and the shared AST helpers in src/utils/ast.ts.
- Register in
src/detectors/index.ts; include in core (and surface the effect case via the react pack) in src/config/packs.ts.
- Docs in
docs/rules.md; fixtures covering awaited, returned, voided, and floating cases.
Acceptance criteria
Difficulty: medium.
Summary
Add a detector for floating/unawaited promises — async calls whose returned promise is neither awaited, returned, nor
.catch-handled — including fire-and-forget async work started inside React effects.Motivation
Unawaited promises cause silent failures, race conditions, and unhandled rejections. They are easy to introduce when editing quickly and are not covered by any current rule. This pairs naturally with
effect-complexityfor the React case.Proposed behavior
floating-promise: a call to a function known/inferred to return a promise (async function,.then-able, or common APIs likefetch) used as an expression statement withoutawait,return,void, or.catch(...).useEffectwithout cleanup/handling.void expras an explicit opt-out, matching common lint conventions).Implementation surface
src/detectors/floatingPromise.tsusing ts-morph type/heuristic inference and the shared AST helpers insrc/utils/ast.ts.src/detectors/index.ts; include incore(and surface the effect case via thereactpack) insrc/config/packs.ts.docs/rules.md; fixtures covering awaited, returned, voided, and floating cases.Acceptance criteria
.catch-handled calls.npm run test:allpasses.Difficulty: medium.