All bytes
ProgrammingFriday, 05 June 2026 · 13:22 EAT

A good default is never silence

When a function returns a falsy value on failure instead of throwing, the caller cannot tell 'nothing found' from 'something broke.' Fail loud, fail early, fail visibly.

When a function returns null, undefined, or an empty value on failure instead of throwing or returning a Result type, the caller has no way to distinguish "nothing found" from "something went wrong." The error is invisible until it causes a downstream failure in a completely different part of the system — and by then the evidence chain is cold.

Three common patterns produce this trap: returning null or undefined on error and forcing every caller to remember to check it; catching an exception and returning a safe default; or setting a flag deep in a conditional that never gets checked. Each one trades immediate convenience for delayed debugging pain. The delay means the debugging starts with fewer clues, more assumptions, and sometimes a different engineer entirely.

Better approaches: throw and let the framework's error handler deal with it; return a discriminated union or Result type so the happy path and the error path are both typed; or at minimum log the failure before returning the default. The goal is not to eliminate defaults — sometimes a fallback is the right business decision. It is to make sure every failure path is visible to someone who can act on it, at the moment it happens.

Takeaway

A default that hides an error is worse than an error that stops the system. Failure should be visible, not silent.