Unreachable Catch Clause

ID

java.unreachable_catch_clause

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Java

Tags

dead-code, reliability

Description

Reports a catch clause — or, inside a multi-catch, one of the types it lists — that can never run because every checked exception it could catch on this try statement is already intercepted by an earlier, narrower catch clause.

Only analysed when the try body’s possible exceptions are visible directly as throw new X(…​) statements: a method call anywhere in the body could throw anything, so this rule stays silent the moment one appears.

Rationale

Catching a derived exception type before its base type is a common, deliberate pattern — the derived handler runs first and gets first refusal. The mistake this rule targets is when the base clause is added afterwards and ends up catching nothing at all, because every exception the try body can actually raise is already a type the earlier, more specific clause absorbed. The handler still reads like live error-recovery code; it simply never executes.

try {
  throw new InvalidOrderException("missing SKU");
} catch (InvalidOrderException e) {
  reject(e);
} catch (OrderException e) { // unreachable: only InvalidOrderException can reach here
  logAndRetry(e);            // this recovery path never runs
}

Remediation

Remove the unreachable clause (or the unreachable type from the multi-catch), or reorder the clauses so the intended handler actually gets a turn:

try {
  throw new InvalidOrderException("missing SKU");
} catch (InvalidOrderException e) {
  reject(e); // the only case that can occur here
}

© 2026 Xygeni. All rights reserved