Skip to main content
ai-slop/redundant-try-catchmanual fix

Redundant try/catch.

A try/catch whose catch only rethrows the same error. It adds nesting and implies handling that does not exist.

Flagged shape and clean shape.

Each example shows the exact code shape the rule is looking for, then the smallest version that keeps the intent without hiding risk or adding noise.

redundant-try-catch.ts
✗ Flagged
export async function loadProfile(userId: string) {
  try {
    return await api.get(`/users/${userId}/profile`)
  } catch (error) {
    throw error
  }
}
Why this trips

Deterministic AST match on JS/TS: flags try statements without `finally` whose catch body is a single `throw err` or `return Promise.reject(err)` of the caught binding.

redundant-try-catch.ts
✓ Clean
export async function loadProfile(userId: string) {
  return api.get(`/users/${userId}/profile`)
}
What changed

Remove the try/catch and let the error propagate, or add the context, cleanup, or recovery that would justify it.

Agents wrap calls in try/catch defensively, then have nothing to do in the catch, so they rethrow the error unchanged.

How this rule is justified.

Rule id

ai-slop/redundant-try-catch

Enforcing engine

ai-slop

Detector strategy

Deterministic AST match on JS/TS: flags try statements without `finally` whose catch body is a single `throw err` or `return Promise.reject(err)` of the caught binding.

Legitimate code that is NOT flagged

Catches that add context (`throw new Error('...', { cause: err })`), log, clean up, or recover, and any try with a `finally` block, are not flagged.

Evidence

Part of aislop's defensive-pattern detectors for JavaScript and TypeScript, scored in the maintainability tier.