Replace Exception with Precheck

Removes smells
Symptom

Code that uses try/catch for conditions the caller could check directly — `try { amounts[i] / 100 } catch { return 0 }` where checking bounds is mechanical.

Goal

Exceptions used for predictable, checkable conditions become an explicit precheck the caller can perform, leaving exceptions for truly exceptional cases.

Before the refactoring

try {
return amounts[i] / 100;
} catch (e) {
return 0;
}

After the refactoring

if (i >= amounts.length) return 0;
return amounts[i] / 100;
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure

Exception flow obscures the rule; debuggers stop on benign throws; reasoning about the happy path requires reading the catch handler.

Tradeoff

Race conditions: the precheck may pass and the operation still fail (TOCTOU). Use prechecks only for conditions the caller can verify without a race.

Relief

The error path is local and visible; reading code top-to-bottom describes the rules rather than the failure response; debuggers stop catching benign throws.

Trap

Replacing every exception with a precheck — including ones for conditions the caller can't atomically verify (TOCTOU race windows).