Review error handling, input validation, and exception patterns using 24-item checklist. Use when auditing defensive code, designing barricades, choosing assertion vs error handling, or deciding correctness vs robustness strategy. Triggers on: empty catch blocks, missing input validation, assertions with side effects, wrong exception abstraction level, garbage in garbage out mentality, deadline pressure to skip validation, trusted source rationalization. Produce status table with VIOLATION/WARNING/PASS per item, or barricade/error-handling design recommendations.
Defensive code keeps small failures from compounding into silent, hard-to-diagnose ones. These four checks catch the violations that corrupt data and hide bugs rather than crashing loudly — each is almost always required; exceptions need explicit justification:
| Check | Why | |---|---| | No executable code in assertions | Assertions are compiled out of production builds; the code vanishes with them | | No empty catch blocks | Silently swallows bugs that cascade into harder failures downstream | | External input validated at entry | Unvalidated input is security vulnerabilities and data corruption | | Assertions for bugs only | Anticipated runtime errors need handling, not assertions (which are disabled in production) |
Shared thresholds and the information-hiding rationale: Read(${CLAUDE_PLUGIN_ROOT}/references/cc-foundations.md).
External input = any data not provably controlled by the current code path: user input, files, network/API/DB responses, environment variables, and data from any other service.
Security-critical code (authentication, authorization, cryptographic operations, PII handling) is never exempt, regardless of the above. When in doubt, validate.
Execute the defensive-programming, assertion, and exception checklists against the code: Read(${CLAUDE_SKILL_DIR}/checklists.md). Output one row per item: | Item | Status | Evidence | Location |, status ∈ VIOLATION (missing validation, empty catch, side-effecting assertion) / WARNING (inconsistent handling, missing docs) / PASS.
Produce assertion placement, error-handling strategy, barricade architecture, and validation implementations. Search the codebase for the existing error-handling pattern (exception vs return code vs Result type, custom exception classes, logging conventions) and follow it — consistency in error handling is what makes failures debuggable. Full gate: Read(${CLAUDE_PLUGIN_ROOT}/references/pattern-reuse-gate.md).
| Condition | Assertion | Error handling | |---|---|---| | Should never occur (programmer bug) | Yes | No | | Can occur at runtime / anticipated bad input | No | Yes | | External input | No | Yes — always validate | | Internal interface, same module | Yes | No | | Internal interface crossing a trust boundary | Yes | Yes | | Public-API precondition violation | Yes | Yes | | Security-critical / highly robust system | Both | Both (defense in depth) |
When a condition is genuinely unclear ("is this a bug or expected?"), clarify requirements with a domain expert rather than guessing.
| Domain | Lean toward | Key question | |---|---|---| | Safety-critical (medical, aviation) | Correctness | — | | Enterprise/B2B, financial, data pipelines | Correctness | Would wrong data drive a bad business decision? Does downstream assume integrity? | | SaaS platforms | Balanced | Blast radius of a wrong answer vs unavailability? | | Consumer apps, internal tools | Robustness | Can the user recover from a crash? | | Real-time systems | Context-dependent | Is stale data better or worse than no data? |
Class-level barricade: public methods validate and sanitize; private methods within that class may assume safe data.
Choose one and apply it consistently — error handling is an architectural decision.
| Strategy | Use for | |---|---| | Return neutral value | Display defaults, non-critical config | | Substitute next valid data | Streaming/sensor data with redundancy | | Return previous answer | Display refresh, non-critical caching (never financial data) | | Substitute closest legal value | Input clamping, slider bounds | | Log warning and continue | Non-critical degradation, feature flags | | Return error code | APIs with status conventions, C-style interfaces | | Centralized error handler | Consistent logging, monitoring integration | | Display error message | User-facing apps (don't leak security info) | | Shut down gracefully | Safety-critical, data-corrupting errors |
Synchronous exception propagation assumes a synchronous call stack; these patterns need explicit handling:
callback(error, result) pattern or wrap in promises.Promise.all — first rejection loses other results; use allSettled and decide fail-entirely vs partial.Make errors loud during development so they're found early; make them unobtrusive with graceful recovery in production. Techniques: make asserts abort, fill allocated memory and freed objects with junk, fail hard on default/else clauses, email error logs to yourself.
| After | Next |
|---|---|
| Validation complete | Skill(code-foundations:cc-control-flow-quality) |
npx skills add ryanthedev/cc-defensive-programming下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer