Flags catch blocks that replace the original failure with a default value or generic error.
- Family:
defensive - Severity:
strong - Scope:
file - Requires:
file.tryCatchSummaries
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.
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");
}
}export function readConfig(raw: string) {
try {
return JSON.parse(raw);
} catch (error) {
logger.error({ error });
throw error;
}
}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.
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.
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