Skip to content

eslint-factory: no-empty-catch-block has no coverage for empty Promise .catch(() => {}) entrypoint handlers #52845

Description

@github-actions

Problem

no-empty-catch-block only fires on the CatchClause AST node — i.e. try { } catch { } syntax. It has no coverage for the functionally identical anti-pattern where a Promise chain ends in an empty .catch(() => {}) callback, which silently swallows a rejection with zero diagnostics — exactly the "hidden failures that are hard to diagnose from CI logs" risk this rule exists to catch.

No sibling rule fills the gap either:

  • require-async-entrypoint-catch (require-async-entrypoint-catch.ts:15-28, chainHasCatch) only checks that a .catch(...) call is present somewhere in the chain — it never inspects whether the callback body actually does anything.
  • no-unsafe-promise-catch-error-property only fires when the callback does access err.message/.stack/etc. unsafely; a callback that never touches err at all (an empty one) is outside its selector entirely.

Grounded live sites

  • actions/setup/js/action_setup_otlp.cjs:198: run().catch(() => {});
  • actions/setup/js/action_conclusion_otlp.cjs:98: run().catch(() => {});

Both are preceded by an explicit comment ("Non-fatal: errors are silently swallowed.") documenting that this is deliberate — OTLP export failures shouldn't fail the job. So today these are legitimate, not bugs. But that is precisely why a new check needs a comment-based exemption identical to no-empty-catch-block's (see the sibling issue on broadening that vocabulary), rather than blanket-flagging every empty .catch() — and until such a check exists at all, an accidentally empty entrypoint .catch(() => {}) introduced elsewhere in the codebase would go completely undetected by any current rule.

Ask

Extend no-empty-catch-block (or add a CallExpression selector alongside its existing CatchClause one) to also flag .catch(callback) calls whose callback has a genuinely empty body, when no comment nearby matches the same intent-signaling vocabulary used for CatchClause. Reuse the same comment-adjacency exemption logic (leading comment inside/immediately above the callback body) so the two documented live sites (action_setup_otlp.cjs:198, action_conclusion_otlp.cjs:98) stay valid once the broadened vocabulary from the sibling issue lands.

Acceptance criteria

  • New selector (or new rule) flags .catch(() => {}) / .catch(function () {}) with a genuinely empty body and no adjacent explanatory comment.
  • action_setup_otlp.cjs:198 and action_conclusion_otlp.cjs:98 do NOT flag, given their existing "Non-fatal: errors are silently swallowed." comment (matched against the broadened vocabulary from the sibling issue).
  • A synthetic case with an undocumented empty .catch(() => {}) is added as an invalid test case.
  • Non-empty .catch(err => { ...body... }) callbacks remain unaffected (no new false positives on the existing corpus).

Generated by 🤖 ESLint Refiner · agent · 201.6 AIC · ⌖ 4.82 AIC · ⊞ 5.2K ·

  • expires on Aug 21, 2026, 9:28 PM UTC-08:00

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

cookieIssue Monster Loves Cookies!eslint

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions