Standardize application error handling—taxonomy, propagation, response shapes, logging, and correlation IDs—when the task is to improve consistency of existing error behavior across a codebase.
Installation
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Standardize application error handling—taxonomy, propagation, response shapes, logging, and correlation IDs—when the task is to improve consistency of existing error behavior across a codebase.
Error Handling
Overview
Standardize error handling across a codebase by implementing a unified error
taxonomy, stable error codes, proper propagation chains, and structured logging.
The core principle: every error must be categorized, coded, wrapped with
context, and split into a safe user-facing message and a detailed internal log
entry.
When to use
The task is to standardize how an existing codebase models, propagates, logs, and returns errors.
The user needs an error taxonomy, error classes, response envelopes, or correlation-aware logging patterns.
The problem is inconsistency across layers, services, or endpoints rather than a single failing bug.
The deliverable is an error-handling framework or pattern, not one-off troubleshooting.
Do NOT use when:
The task is debugging a specific runtime failure.
The request is about monitoring, alert routing, or dashboards rather than application error design.
The work is only input validation or business rules with no broader error-model concern.
Response format
Always structure the final response with these top-level sections, in this order:
Summary — state the task, scope, and main conclusion in 1-3 sentences.
Decision / Approach — state the key classification, assumptions, or chosen path.
Artifacts — provide the primary deliverable(s) for this skill. Use clear subheadings for multiple files, commands, JSON payloads, queries, or documents.
Validation — state checks performed, important risks, caveats, or unresolved questions.
Next steps — list concrete follow-up actions, or write None if nothing remains.
Rules:
Do not omit a section; write None when a section does not apply.
If files are produced, list each file path under Artifacts before its contents.
If commands, JSON, SQL, YAML, or code are produced, put each artifact in fenced code blocks with the correct language tag when possible.
Keep section names exactly as written above so output stays predictable across skills.
Workflow
1. Audit existing error handling
Scan the codebase for current error patterns:
Search for try/catch, try/except, .catch(), rescue, error middleware
Note inconsistent error response formats across endpoints
Check for leaked internal details in user-facing responses
Output: A list of error handling gaps and inconsistencies.
2. Define the error taxonomy
Create error categories that map to HTTP status codes (for APIs) or exit
conditions (for services). Every error in the system must belong to exactly one
category.
Category
HTTP Status
Error Code Prefix
Description
validation
400
ERR_VALIDATION_
Invalid input, malformed request
authentication
401
ERR_AUTH_
Missing or invalid credentials
authorization
403
ERR_FORBIDDEN_
Valid credentials but insufficient access
not_found
404
ERR_NOT_FOUND_
Requested resource does not exist
conflict
409
ERR_CONFLICT_
State conflict (duplicate, version mismatch)
rate_limit
429
ERR_RATE_LIMIT_
Too many requests
internal
500
ERR_INTERNAL_
Unexpected server error
service_unavailable
503
ERR_UPSTREAM_
Dependency failure (DB, external API)
3. Implement error class hierarchy
Create a base error class and category-specific subclasses. Every error class
must carry:
code — Stable string code clients can match on (e.g.,
ERR_USER_NOT_FOUND)
message — Safe, user-facing message (no stack traces, no internal paths)
statusCode — HTTP status code for API responses
category — Error taxonomy category
details — Optional structured data (field validation errors,
constraints)
cause — Original error for propagation chain (preserves stack trace)
Never swallow exceptions. Every catch block must either:
Re-raise the error unchanged (if this layer can't add context)
Wrap the error in a domain-specific error with the original as cause
Handle the error completely (log it, return a response, trigger recovery)
Always preserve the chain. When wrapping, pass the original error as cause
so the full stack trace is available in logs:
// WRONG: swallows the original errortry {
await db.query(sql);
} catch (err) {
thrownewError("Database query failed"); // original error lost
}
// RIGHT: wraps with context, preserves causetry {
await db.query(sql);
} catch (err) {
thrownewInternalError("Database query failed", err asError);
}
5. Separate user-facing from internal errors
User-facing response — safe, minimal, actionable:
{"error":{"code":"ERR_NOT_FOUND_USER","message":"User not found","details":{"resource":"user","identifier":"usr_abc123"}},"requestId":"req_7f3a2b1c"}
Internal log entry — full diagnostic context:
{"level":"error","code":"ERR_NOT_FOUND_USER","message":"User not found","category":"not_found","correlationId":"req_7f3a2b1c","userId":"usr_abc123","path":"/api/users/usr_abc123","method":"GET","stack":"NotFoundError: User not found\n at UserService.getById ...","cause":"MongoError: connection refused at 10.0.0.5:27017","timestamp":"2026-03-06T10:15:32.456Z","service":"user-api","environment":"production"}
Rules:
Never expose stack traces, file paths, or database errors to users
Never expose internal service names or infrastructure details
Always include the error code in both user response and log
Always include a requestId / correlationId in both
Log the full causal chain internally; show only the top-level message to users
For InternalError (500), always use a generic message: "An unexpected error
occurred"
6. Implement error response middleware
Centralize error-to-response conversion in middleware (Express) or exception
handlers (FastAPI, Django). This is the single place where errors become HTTP
responses.
Error taxonomy defined with categories mapping to HTTP status codes
Base error class implemented with code, message, statusCode, category,
cause
Category-specific error subclasses created (validation, auth, not-found,
etc.)
Error codes are stable strings clients can match on programmatically
All catch blocks either re-raise, wrap with context, or fully handle
No swallowed exceptions (empty catch blocks)
User-facing responses contain only code, message, and safe details
Internal logs contain full stack traces, causal chains, and request
context
Correlation ID flows through from request to response to logs
Centralized error middleware converts errors to consistent HTTP responses
500 errors always use generic message, never expose internals
Error Response Schema
All API error responses must follow this schema:
{"error":{"code":"ERR_VALIDATION","message":"Invalid email format","details":{"field":"email","constraint":"Must be a valid email address","received":"not-an-email"}},"requestId":"req_7f3a2b1c"}
Field
Type
Required
Description
error.code
string
Yes
Stable error code for programmatic matching
error.message
string
Yes
Human-readable description, safe for users
error.details
object
No
Structured context (validation fields, etc.)
requestId
string
Yes
Correlation ID for support and debugging
Common mistakes
Mistake
Fix
Swallowing exceptions in empty catch blocks
Every catch must re-raise, wrap, or fully handle. Log at minimum.
Leaking stack traces to API consumers
Error middleware must strip internals. Only expose code + message + safe details.
Using HTTP status codes as error codes
Status codes are transport-level. Use stable string codes (ERR_USER_NOT_FOUND) for programmatic use.
Inconsistent error response format
Centralize in error middleware. Every error response uses the same JSON schema.
Throwing raw strings instead of error objects
Always throw typed error instances with code, category, and cause chain.
Missing correlation IDs
Generate a request ID at the edge (middleware/gateway) and propagate through all layers and logs.
Logging user-facing message only
Internal logs must include stack trace, cause chain, request context, and correlation ID.
Different error formats per endpoint
One error middleware, one response schema. Endpoints throw typed errors; middleware formats responses.
Catching too broadly (catch Exception)
Catch specific error types when possible. Use broad catch only at the top-level error boundary.
Not distinguishing operational vs programmer errors
Operational errors (bad input, not found) are expected. Programmer errors (null deref) need alerts.
Key principles
Every error gets a stable code — HTTP status codes change meaning across
contexts. String error codes like ERR_USER_NOT_FOUND are stable contracts
that clients, monitoring, and documentation can rely on. Never use numeric
codes alone.
Never swallow, always wrap — Empty catch blocks hide bugs. Every caught
error must be re-raised, wrapped with domain context (preserving the original
as cause), or fully handled. The causal chain must survive from origin to
log.
User-facing and internal are separate concerns — Users see a safe message
and an error code. Logs see the full stack trace, causal chain, correlation
ID, and request context. The error middleware is the boundary between these
two worlds.
Correlation IDs connect everything — A single request ID generated at the
edge must appear in the HTTP response, every log entry, and any downstream
service calls. Without this, debugging production errors across services is
impossible.
Centralize the error boundary — One error middleware, one response
schema, one logging format. Individual endpoints throw typed errors; they
never format error responses directly. This eliminates inconsistency.
Optimization Notes
Preserve the user's requested output shape exactly and do not substitute generic advice for concrete artifacts.
Include exact commands, code structures, protocol fields, tags, parameters, file paths, or deliverable sections when the task asks for them.
Make safety gates explicit before irreversible, destructive, externally visible, or compliance-sensitive actions.
For multi-step work, present steps in execution order and include validation or rollback checks where relevant.
Avoid overfitting to a single eval example: express lessons as reusable rules, not as task-specific answers.