Description
The require-fetch-try-catch ESLint rule in eslint-factory/src/index.ts has a false negative: isAwaitFetchCall only matches an awaited CallExpression whose callee is the bare fetch Identifier. Any member-chained call (await fetch(url).then(...), .catch(...), .json()) has a MemberExpression callee and is silently ignored — including bare .then() chains without a rejection handler, which would crash on a network TypeError.
Grounded example: validate_secrets.cjs:65,85 — await fetch(...).catch(rethrowAbortError) escapes detection. While safe today (via outer try), the shape silently bypasses the rule and could mask future violations of the same pattern.
Suggested Changes
- Extend
isAwaitFetchCall to also recognize await fetch(...).method(...) chains where fetch is the root callee
- Add logic to determine if a chain is "safe": terminal
.catch(handler) or 2-arg .then(onFulfilled, onRejected) should be treated as satisfying the requirement
- Add test cases:
await fetch(url).json() with no try/catch — invalid (should flag)
await fetch(url).catch(handler) — valid (should not flag)
await fetch(url).then(ok, err) — valid (should not flag)
await fetch(url).then(ok) — invalid (no rejection handler)
Files Affected
eslint-factory/src/index.ts (require-fetch-try-catch rule, isAwaitFetchCall helper)
eslint-factory/src/tests/ (add test cases for chained patterns)
Success Criteria
Priority
Medium — prevents real-world fetch chain crashes from escaping detection
Source
Extracted from ESLint Refiner Daily Report 2026-07-25 discussion #47933
🔍 Task mining by Discussion Task Miner - Code Quality Improvement Agent · sonnet46 · 54.5 AIC · ⌖ 8.48 AIC · ⊞ 7.1K · ◷
Description
The
require-fetch-try-catchESLint rule ineslint-factory/src/index.tshas a false negative:isAwaitFetchCallonly matches an awaitedCallExpressionwhose callee is the barefetchIdentifier. Any member-chained call (await fetch(url).then(...),.catch(...),.json()) has aMemberExpressioncallee and is silently ignored — including bare.then()chains without a rejection handler, which would crash on a networkTypeError.Grounded example:
validate_secrets.cjs:65,85—await fetch(...).catch(rethrowAbortError)escapes detection. While safe today (via outer try), the shape silently bypasses the rule and could mask future violations of the same pattern.Suggested Changes
isAwaitFetchCallto also recognizeawait fetch(...).method(...)chains wherefetchis the root callee.catch(handler)or 2-arg.then(onFulfilled, onRejected)should be treated as satisfying the requirementawait fetch(url).json()with no try/catch — invalid (should flag)await fetch(url).catch(handler)— valid (should not flag)await fetch(url).then(ok, err)— valid (should not flag)await fetch(url).then(ok)— invalid (no rejection handler)Files Affected
eslint-factory/src/index.ts(require-fetch-try-catchrule,isAwaitFetchCallhelper)eslint-factory/src/tests/(add test cases for chained patterns)Success Criteria
await fetch(url).json()outside a try is flaggedawait fetch(url).catch(handler)is not flaggedawait fetch(url).then(ok, err)is not flaggedawait fetch(url).then(ok)(1-arg) is flaggedPriority
Medium — prevents real-world fetch chain crashes from escaping detection
Source
Extracted from ESLint Refiner Daily Report 2026-07-25 discussion #47933