Use when writing anything that can fail — I/O, network, database, parsing, user input — when deciding whether to throw, return, retry, log or swallow, and when a production error is unhelpful ('something went wrong') or duplicated across logs.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add connorpham/vteam-harness --skill dev-error-handling --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Dev Error Handling?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/connorpham-dev-error-handling)More formats (shields.io, HTML) on the badges page.
---
name: dev-error-handling
description: "Use when writing anything that can fail — I/O, network, database, parsing, user input — when deciding whether to throw, return, retry, log or swallow, and when a production error is unhelpful ('something went wrong') or duplicated across logs."
---
# Error handling — fail fast, fail loud, fail once
## Identity
You separate what *can* go wrong (operational: network, disk, bad input) from
what *must not* (programmer errors: null where a value is guaranteed, an
impossible enum). The first you handle at the boundary with a good message;
the second you let crash loudly so it gets fixed. You never write `catch {}`
and you never log an error twice.
## When this applies
- Every call that touches I/O, another service, the database, or user input.
- Any `try`/`catch`, `.catch`, `Result`, or error return you write.
- A retry, timeout, fallback or "default value on failure".
- Reading a log or error report that does not say what happened.
## Decide
| Situation | Do | Because |
|---|---|---|
| Expected failure (validation, not found, conflict) | Return it as data (typed result / domain error) | Callers must handle it; a throw is easy to forget |
| Unexpected failure (bug, invariant broken) | Throw/raise; let the top-level handler log and crash the request | Recovering from a bug hides it |
| Third-party call fails | Wrap in a domain error with context; keep the cause | The caller needs "payment declined", not `ECONNRESET` |
| Retry? | Only idempotent operations, bounded attempts, backoff with jitter | Unbounded retries turn an outage into a self-DDoS |
| Where to log | Once, at the boundary that handles it, with correlation id | Log-and-rethrow doubles every error in the aggregator |
| User-facing message | From the spec verbatim when it exists; never the internal message | Internals leak; spec messages are the contract |
| Partial failure in a batch | Report per item; never "some failed" | The operator must know which |
## Rules
- **Validate at the edge, trust inside.** Parse the request into a typed value
once; inner code assumes validity. *Otherwise:* every function defends against
every input and none of them agree.
- **Fail fast.** Check preconditions first; do no side effect before all inputs
are known good. *Otherwise:* a half-applied operation is the hardest bug class.
- **Preserve the cause.** Wrap with context (`what`, `which id`), keep the
original as `cause`. *Otherwise:* the stack trace points at your wrapper.
- **No empty catch, no catch-all that continues.** `catch (e) {}` and
`except Exception: pass` are prohibited. *Otherwise:* the failure surfaces
three layers away as corrupted data.
- **Cleanup is unconditional**: `finally`, `defer`, context managers, `using`.
*Otherwise:* the connection pool leaks one handle per failure.
- **Messages say what happened and what to do**, with identifiers: "Order 4711:
payment declined by provider (code 51); no retry" — not "error processing
order". *Otherwise:* the on-call engineer opens a debugger for a known case.
- **Timeouts on every outbound call.** *Otherwise:* one slow dependency holds
every worker.
## Reviewer lens
- Find every `catch`; what does each one do with the error? Any that swallow?
- Trace one failure path end to end: how many times is it logged?
- Is any non-idempotent operation retried?
- Do outbound calls have timeouts?
## Sources
nodebestpractices §2 Error Handling (operational vs programmer errors, central
handler, no swallow) · wshobson/agents `error-handling-patterns` (exceptions vs
Result, cleanup, pitfalls) · OWASP Error Handling & Logging cheat sheets.
Rationalizations, red flags and a worked example live in `reference/dev-error-handling.md` — opened when needed, never loaded by default.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!