Skillshub Common Error Handling

Cross-cutting standards for error design, response shapes, error codes, and boundary placement. Use when handling errors, designing exception flows, or standardizing error responses.

install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/HoangNguyen0403/agent-skills-standard/error-handling" ~/.claude/skills/comeonoliver-skillshub-common-error-handling-063e59 && rm -rf "$T"
manifest: skills/HoangNguyen0403/agent-skills-standard/error-handling/SKILL.md
source content

Common Error Handling Standards

Priority: P1 (OPERATIONAL)

Consistent, predictable error handling is the backbone of maintainable systems. Errors are first-class citizens — design them explicitly.

🏗 Error Response Shape (HTTP APIs)

All API errors MUST use a consistent envelope:

{
  "error": {
    "code": "USER_NOT_FOUND",
    "message": "The requested user does not exist.",
    "traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
    "details": []
  }
}
FieldRule
code
SCREAMING_SNAKE_CASE machine-readable code. Never localize.
message
Human-readable English summary. Safe for end-users (no stack traces).
traceId
Correlation ID from the request context.
details
Optional array of field-level validation errors. Empty for non-validation errors.

🗂 Error Classification

LayerError TypeStrategy
Validation
400 Bad Request
Return
details[]
with field paths
Authentication
401 Unauthorized
Generic message — never expose reason
Authorization
403 Forbidden
Log attempt, never expose role info
Not Found
404 Not Found
Distinguishable from auth errors
Conflict
409 Conflict
Include conflicting resource ID
Unhandled
500 Internal Server Error
Log full context, return generic message

📦 Error Wrapping vs Replacement

  • Wrap when adding context:
    fmt.Errorf("processOrder: %w", err)
    (Go) /
    new ServiceError('msg', { cause: err })
    (JS).
  • Replace only when the original error leaks sensitive internal details.
  • Never swallow: Catch without logging or re-throwing hides bugs — forbidden.

🛡 Boundary Placement

  • API Layer: Translate domain/infrastructure errors into HTTP responses. Use a global exception filter/middleware.
  • Domain Layer: Throw domain-specific errors (e.g.,
    InsufficientStockError
    ). Never reference HTTP status codes.
  • Infrastructure Layer: Throw infrastructure errors (e.g.,
    DatabaseConnectionError
    ). Wrap 3rd party exceptions.
  • Never: Let infrastructure errors (raw DB/network exceptions) bubble up to the API response.
Request → [API Layer: maps to HTTP] → [Domain: business errors] → [Infra: DB/network errors]

🔢 Error Code Design

  • Codes are permanent IDs — treat them like API contracts. Once published, never rename.
  • Format:
    <DOMAIN>_<NOUN>_<VERB>
    ORDER_PAYMENT_FAILED
    ,
    USER_EMAIL_DUPLICATE
    .
  • Define in a centralized constants file; never inline magic strings.

Anti-Patterns

  • No
    catch(e) {}
    : Always log or re-throw.
  • No stack traces in responses: Leak internal structure to attackers.
  • No generic
    500
    for validation
    : Use
    400
    with
    details
    .
  • No HTTP status codes in domain layer: Domain errors are business concepts, not transport decisions.
  • No error-code proliferation: Prefer a small, well-documented set over one code per exception class.