spb/ultra-sharp-agent-skills Public
Ultra-Sharp Agent Skills — a research-first skill-authoring system + 72 production-ready skills for AI agents.
Python 100%
1---2name: handling-errors3description: Designs error handling for backend services — error taxonomy, HTTP problem+json responses (RFC 9457), retry semantics with backoff and jitter, circuit breakers, and fail-fast startup. Use when the user asks how to handle, structure, or standardize errors or exceptions in an API or service, design error responses, add retries or a circuit breaker, or fix swallowed/double-logged exceptions. Do not use for validating request input (validating-input) or for logging/metrics/tracing pipelines (instrumenting-observability).4---56<!--7Author: Simon-Pierre Boucher8Contact: contact@spboucher.ai9-->1011# Handling Errors1213## When to use / when NOT to use14- **Use for:** structuring errors and exceptions in backend code, API error responses, retry/circuit-breaker policy, startup failure behavior.15- **Do NOT use for:** request-validation rules and 400-level field errors (validating-input) or log/metric/trace plumbing (instrumenting-observability).1617## Core rules18191. **Expected failures are values, exceptional failures are exceptions.** "User not found" is a normal outcome — return it. A broken DB socket is exceptional — raise it. Follow the language idiom (Result/Either in Rust/TS-fp, exceptions in Python/Java).202. **Keep the taxonomy small.** 4–6 error classes mapped to HTTP: `ValidationError`→400, `AuthError`→401/403, `NotFound`→404, `Conflict`→409, `RateLimited`→429, everything else→500. New error types must argue their way in.213. **API errors are problem+json (RFC 9457).**22 - ✅ `{"type":"https://api.example.com/errors/quota","title":"Quota exceeded","status":429,"detail":"Plan allows 100 reports/day.","instance":"/reports/123"}`23 - ❌ `{"error": "something went wrong"}` or a raw stack trace.244. **Log or re-raise — never both.** Handling an exception twice produces double logs and masks the real failure point. Catch only where you can act; add context and re-raise otherwise.25 - ✅ `except PaymentError as e: raise OrderError(order_id=id) from e`26 - ❌ `except Exception: logger.error(e); raise` at every layer.275. **User-facing messages say what to do next; internals stay in logs.** ✅ "Payment declined — try another card." ❌ "psycopg2.OperationalError: connection refused at 10.0.3.7:5432".286. **Retry only idempotent operations,** with exponential backoff + full jitter (base 200 ms, factor 2, cap 30 s, max 5 attempts — bounded work, no thundering herd) and respect `Retry-After` when present.297. **Wrap flaky dependencies in a circuit breaker** (open after 5 consecutive failures, half-open probe after 30 s) so one dead downstream doesn't exhaust your threads.308. **Fail fast at startup.** Missing config, unreachable migrations, bad credentials → crash with a named cause before serving traffic. Never boot into a half-working state.3132## Workflow33341. List the operation's failure modes; split expected vs exceptional.352. Map each to the taxonomy (rule 2) and its HTTP status; add a new class only if none fits.363. Implement handlers at the boundary layer only (HTTP middleware / job wrapper), converting taxonomy → problem+json.374. Add retry/breaker policy for each external dependency (rules 6–7).385. Validate: trigger each failure mode in a test — assert the status code, the problem+json shape, exactly one log entry per failure, and no stack trace in the response body.3940## Edge cases & failure modes41- **Partial failure in a batch** → return 207-style per-item results or a summary object; never fail the whole batch silently.42- **Retryable error during a non-idempotent call** → do not retry; surface it. Make the call idempotent first (idempotency keys) if retries are required.43- **Error while handling an error** (e.g., logger down) → last-resort handler writes to stderr and returns a static 500 body; never raise from the handler.44- **Timeout vs failure ambiguity** → treat timeouts as unknown-outcome: only retry with an idempotency key.4546## References47Deeper recipes and gotchas: see [references/patterns.md](references/patterns.md)48