Barricade Your Program to Contain
the Damage Caused by Errors
Definition
In software construction, “barricading” a program
means designing it so that when something goes
wrong, the failure stays local, is detected quickly, and
the rest of the system keeps working
Why barricade failures?
Safety: prevent corrupted data, leaks, or security gaps from spreading.
Availability: a single bug or bad input shouldn’t bring down the whole
system.
Observability & recovery: localized failures are easier to detect, debug,
and fix.
User experience: graceful degradation keeps users working even when
parts fail.
Key principles
1. Fail fast & fail safe — detect errors early; prefer stopping an
operation rather than continuing in corrupt state.
2. Least privilege / encapsulation — reduce what each component
can affect.
3. Defense in depth — multiple layers of protection (validation,
checks, retries, timeouts).
4. Isolation — isolate risky code so problems don’t cross
boundaries.
Practical techniques and patterns
1) Input validation & sanitization
Validate all external inputs (users, network, files).
Check types, ranges, formats, lengths.
Reject/normalize bad inputs before any processing.
Example: refuse negative quantities, invalid JSON, or oversized uploads.
Use exceptions/returns correctly
Handle errors at the right level.
Low-level code should raise/return precise errors.
Higher-level code decides whether to retry, transform, or fail
Defensive programming & assertions
Use assertions and invariant checks during development.
In production, still validate assumptions and convert assertion failures to safe errors.
Logging, monitoring, tracing, alerts
Log contextual, structured errors (not just “failed”).
Emit metrics (error rate, latency) and traces to find where errors propagate.
Alert on meaningful thresholds so you can act quickly.