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
}