Skip to content

Latest commit

 

History

History
88 lines (66 loc) · 2.21 KB

File metadata and controls

88 lines (66 loc) · 2.21 KB

defensive.error-obscuring

Flags catch blocks that replace the original failure with a default value or generic error.

  • Family: defensive
  • Severity: strong
  • Scope: file
  • Requires: file.tryCatchSummaries

How it works

The rule reports small try/catch blocks when the catch clause does one of these things:

  • returns a default literal
  • throws a generic replacement error
  • logs and then returns a default

Those patterns make downstream diagnosis harder because the original failure is flattened or hidden.

Flagged examples

export function readConfig(raw: string) {
  try {
    return JSON.parse(raw);
  } catch {
    return {};
  }
}

export function loadProfile(id: string) {
  try {
    return fetchProfile(id);
  } catch {
    throw new Error("failed to load profile");
  }
}

Usually ignored

export function readConfig(raw: string) {
  try {
    return JSON.parse(raw);
  } catch (error) {
    logger.error({ error });
    throw error;
  }
}

How to fix / do this better

Prefer preserving failure meaning instead of replacing it with a cheap fallback.

Better patterns:

  • rethrow the original error
  • wrap with context while preserving cause
  • return a deliberate result type that makes the failure explicit instead of pretending the operation succeeded
export function loadProfile(id: string) {
  try {
    return fetchProfile(id);
  } catch (error) {
    throw new Error(`Failed to load profile ${id}`, { cause: error });
  }
}

If you truly need a fallback value, keep it narrow, document why it is safe, and avoid erasing the original failure in code paths that still need diagnosis.

Scoring

Each flagged catch uses the shared try/catch scoring helper, then the file total is capped at 8. Generic rethrows are still noisy, but scored slightly lower than silent default-return patterns.

Benchmark signal

Small pinned rule benchmark (manifest):

  • Signal rank: #8 of 9
  • Signal score: 0.66 / 1.00
  • Best separating metric: findings / file (0.83)
  • Hit rate: 5/6 AI repos vs 5/5 mature OSS repos
  • Full results: rule signal report