intermediate

Defensive programming

Validate untrusted boundaries and protect invariants without burying normal flow under redundant checks.

Defensive programming validates untrusted input at boundaries—HTTP, queues, user files—and asserts invariants inside domain code. Fail fast with clear errors rather than propagating corrupt state. Balance: not every internal function needs redundant null checks if types and constructors guarantee safety.

Use schema validation (Zod, JSON Schema) at edges; keep core logic clean.

On interviews: place guards for an API handler versus internal pure function and justify.

Common pitfalls: defensive noise obscuring happy path, catching errors too early without context, and trusting client validation only.

The trade-off is redundancy and noise versus fewer mysterious failures in production.

Checklist:

  • Validate at system boundaries.
  • Trust internal contracts when enforced.
  • Fail fast with actionable errors.