Reliabilityerrorrecommended presetstrict preset✓ autofix supported

ai-guard/no-empty-catch

Disallows empty catch blocks that silently swallow exceptions and hide production failures

What it does

Flags `catch` blocks that contain no statements and no explanatory comment. An empty catch block catches an error and immediately discards it, hiding failures from the rest of the application.

Why AI tools generate this pattern

Empty catch blocks are the most common AI-generated error handling pattern. AI tools frequently generate scaffolding code with `try/catch` structures where the catch body is left empty — either as a placeholder or because the training data included examples where errors were intentionally silenced. In production, this means a database write fails, an API call times out, or a file operation errors — and your application continues as if nothing happened. Users see incorrect data or missing UI state with no error in any log.

Code Examples

Incorrect (Flagged by AI Guard)
// The error is caught and immediately discarded
async function saveUser(data: User) {
  try {
    await db.users.insert(data);
  } catch (e) {
    // ← nothing here — the error silently disappears
  }
}
Correct (Safe & Deterministic)
// Log the error
async function saveUser(data: User) {
  try {
    await db.users.insert(data);
  } catch (err) {
    console.error('Failed to save user:', err);
    throw err; // re-throw so the caller knows
  }
}

// Or use a typed error handler
try {
  await fetchData();
} catch (err) {
  if (err instanceof NetworkError) {
    return { error: 'Network unavailable', retry: true };
  }
  throw err;
}

// Intentionally ignored errors can be documented explicitly
try {
  await maybeCleanup();
} catch {
  // intentionally ignored: cleanup is best-effort
}

Safe Autofix

This rule supports a safe autofix. For a truly empty catch block, `--fix` inserts a placeholder comment:

Before fix:

try { await runTask(); } catch (e) {}

After fix:

try { await runTask(); } catch (e) { /* TODO: handle error */ }

How to Fix

  1. At minimum, **log the error**. Preferably:
  2. Log with context (`console.error` or your logger)
  3. Re-throw if the caller needs to know
  4. Return a typed error value if this is expected to fail
  5. If silencing is truly intentional, add a comment explaining why: `// intentionally ignoring — event is best-effort`

Nuances & False Positive Prevention

Legitimate usage can be exempted with inline disable comments (// ai-guard-disable-next-line no-empty-catch) when appropriate.

Configuration

Enable or override this rule in your ESLint configuration:

eslint.config.mjs
// eslint.config.mjs
export default [
  {
    plugins: { 'ai-guard': aiGuard },
    rules: {
      'ai-guard/no-empty-catch': 'error',
    },
  },
];

Related Rules