Skip to content
Back to skills

Error Handling

ASecurity

Use when designing error-handling strategy for a feature — error classification, throw-vs-return conventions, retry/circuit-breaker/fallback decisions, and error-to-user-message mapping. Triggers on "error handling", "retry strategy", "circuit breaker", "error propagation", "错误处理", "重试策略", "熔断", "降级" — also when user says "这个错误该怎么处理" / "要不要重试". Not for diagnosing a specific bug (use debugging); system-level resilience architecture (use architecture).

  • 3 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 4, 2026
ai-agentspythonrustgojavasqldebuggingapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 3 files and shows the line behind each finding

Scanned September 4, 2026

npx -y skills add int2t05/engineering-skills --skill error-handling --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Error Handling?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Error Handling
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/int2t05-error-handling/badge)](https://www.skillsdirectory.com/skills/int2t05-error-handling)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: error-handling
description: Use when designing error-handling strategy for a feature — error classification, throw-vs-return conventions, retry/circuit-breaker/fallback decisions, and error-to-user-message mapping. Triggers on "error handling", "retry strategy", "circuit breaker", "error propagation", "错误处理", "重试策略", "熔断", "降级" — also when user says "这个错误该怎么处理" / "要不要重试". Not for diagnosing a specific bug (use debugging); system-level resilience architecture (use architecture).
---

## When to use

- Designing how errors propagate across layers for a new feature or service boundary
- Choosing retry, circuit-breaker, or fallback strategy for calls to external systems
- Establishing throw-vs-return conventions for a module or codebase
- Mapping internal errors to user-facing messages at an edge boundary

**Not for:** diagnosing a specific bug or test failure (use `debugging`); system-level resilience architecture — cross-service error strategy, overall failure posture (use `architecture`, specifically `architecture/references/error-resilience.md`); API error response envelope shape (use `api-design`); production logging/metrics instrumentation (use `observability`).

## Steps

For system-level resilience architecture (cross-service error propagation, failure posture design), read [architecture's error-resilience reference](${CLAUDE_PLUGIN_ROOT}/skills/03-design/architecture/references/error-resilience.md) first. This skill is the implementation-level companion — the decisions you make at the keyboard when writing the error-handling code.

### 1. Classify errors

Every error falls into one of four categories, and the category drives the strategy:

| Category | Examples | Strategy |
|---|---|---|
| **Transient** | network timeout, 503, connection reset | retry with backoff (step 3) |
| **Permanent** | 404, 400, logic failure | fail fast, no retry |
| **Validation** | bad input, schema mismatch | return 422-style result to caller |
| **Auth** | expired token, insufficient scope | return 401/403, prompt re-auth |

If you can't classify an error, default to permanent — retrying an unclassified error masks real bugs.

### 2. Choose throw-vs-return convention

Pick one convention per layer and enforce it (architecture ref §1 has the full rationale):

- **Throw (exceptions)** for invariant violations and infrastructure failures — "this should never happen, the operation cannot continue." Catch at boundaries, not at every call.
- **Return (Result/error values)** for expected, recoverable failures the caller must branch on — not-found, conflict, validation. A 404 is a result, not an exception.

Follow the language ecosystem's dominant convention: Rust/Go return error values; Python/Java/JS throw. Fighting the ecosystem creates inconsistent code.

### 3. Design retry strategy (transient errors only)

Retry only transient errors. Retrying permanent errors wastes resources and can amplify failures. See [references/retry-patterns.md](references/retry-patterns.md) for formulas and code.

- **Exponential backoff + jitter:** base × 2^n, capped, with jitter to prevent retry stampedes. Full jitter (random between 0 and the capped value) is the safe default.
- **Max attempts:** 3 covers most transient blips. More than 5 rarely helps and delays failure.
- **Idempotency:** retry only idempotent operations (GET, PUT, DELETE with stable IDs). For POST, require an idempotency key so a retry after an ambiguous timeout doesn't double-charge or double-create.
- **Timeout on every call.** A call without a timeout can hang forever and hold resources.

### 4. Add circuit breaker when retry is not enough

Retry handles isolated transient failures. A circuit breaker protects a struggling downstream from retry storms during a sustained outage.

- **States:** closed (normal) → open (fail fast, no calls) → half-open (probe one request to test recovery).
- **Open threshold:** N consecutive failures or a failure-rate threshold (e.g., 50% over a rolling window).
- **Cooldown:** fixed time or exponential reset. Half-open probes one request; success closes, failure re-opens.
- **Use when:** a downstream dependency has repeated sustained outages and retries would make things worse. Don't add a circuit breaker for a call that rarely fails.

### 5. Plan graceful degradation

When a dependency fails, decide what the user gets instead:

- **Critical path** (payment, auth, core data): fail the request — no degradation.
- **Non-critical path** (recommendations, search, analytics): catch the failure, serve a fallback (cached data, empty state, default) — the core page still renders.
- **Feature-flag kill switch:** for integration failures that recur, a flag to disable the feature path instantly beats debugging under load.

### 6. Map errors to user-facing messages (at the edge)

Maintain a single mapping from stable error codes to user-facing messages, at the edge boundary (architecture ref §3):

- **Stable error codes** (`PAYMENT_DECLINED`, `RATE_LIMITED`), not free text. The code is the cross-service contract.
- **Generic external, specific internal:** never expose SQL fragments, stack traces, or internal hostnames to users. Map to "Could not complete this action" + a correlation ID for support.
- **Actionable:** tell the user what to do ("Check your payment details and try again").

### 7. Log with structured context

Log every error with enough context to reproduce the diagnosis without re-running:

- Structured fields: error code, operation, correlation ID, request context.
- No secrets: redact tokens, passwords, PII before logging (see `debugging` skill's redaction discipline).
- Log at the boundary where the error is handled, not at every catch site — duplicated logs obscure the real failure path.

## Verify

- [ ] Every error in the new code is classified (transient / permanent / validation / auth) — strategy follows classification
- [ ] Throw-vs-return convention is consistent within each layer; no exceptions used for expected control flow
- [ ] Retry only fires on transient, idempotent operations; max attempts and backoff are set
- [ ] Circuit breaker (if used) has defined thresholds, cooldown, and half-open probe logic
- [ ] Non-critical dependency failures degrade gracefully (fallback/empty state), not cascade to a full page failure
- [ ] User-facing errors use stable codes + generic messages; no internal details leak
- [ ] Errors are logged with structured context and a correlation ID; no secrets in log output
- [ ] Tests cover: retry on transient, no-retry on permanent, circuit-breaker open/half-open/closed transitions, fallback path

## References

- [${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md](${CLAUDE_PLUGIN_ROOT}/references/engineering-principles.md) — discipline shared by every skill
- [${CLAUDE_PLUGIN_ROOT}/skills/03-design/architecture/references/error-resilience.md](${CLAUDE_PLUGIN_ROOT}/skills/03-design/architecture/references/error-resilience.md) — system-level resilience architecture (cross-layer error propagation, failure posture); this skill is its implementation-level companion
- [references/retry-patterns.md](references/retry-patterns.md) — backoff/jitter formulas, circuit breaker state machine, idempotency-key patterns, retry budgets (with code)

Files in this skill

  • SKILL.md7.2 KB
  • agents/openai.yaml160 B
  • references/retry-patterns.md6.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…