Implement standardized API error handling with RFC 7807 Problem Details responses, centralized error middleware, typed error classes, and environment-aware stack trace exposure. Convert framework exceptions, validation failures, database errors, and upstream service failures into consistent, machine-readable error responses with appropriate HTTP status codes.
try/catch blocks, error middleware, and exception handlers, identifying inconsistent error response formats across endpoints.type (URI identifying error type), title (human-readable summary), status (HTTP code), detail (specific explanation), and instance (request path).ValidationError (400), AuthenticationError (401), AuthorizationError (403), NotFoundError (404), ConflictError (409), and RateLimitError (429).field, message, and code properties.See ${CLAUDE_SKILL_DIR}/references/implementation.md for the full implementation guide.
${CLAUDE_SKILL_DIR}/src/errors/ - Typed error classes (ValidationError, NotFoundError, etc.)${CLAUDE_SKILL_DIR}/src/middleware/error-handler.js - Centralized error handling middleware${CLAUDE_SKILL_DIR}/src/errors/formatters.js - Error-to-RFC-7807 response transformation${CLAUDE_SKILL_DIR}/src/errors/codes.js - Error code registry with human-readable descriptions${CLAUDE_SKILL_DIR}/src/config/error-config.js - Environment-aware error detail configuration${CLAUDE_SKILL_DIR}/tests/errors/ - Error handling tests for each error type and scenario| Error | Cause | Solution |
|---|---|---|
| Stack trace leaked | Error handler omits production check; raw Error thrown without wrapping | Verify NODE_ENV/APP_ENV check in error formatter; wrap all thrown errors in typed classes |
| Inconsistent error format | Some endpoints return {error: "msg"} while others return RFC 7807 |
Ensure all errors flow through centralized middleware; remove per-handler try/catch that formats differently |
| Unhandled promise rejection | Async handler throws without catch; Express does not catch async errors | Use express-async-errors wrapper or explicit async error forwarding with next(err) |
| Database error exposed | Raw SQL error message returned to client containing table/column names | Map database errors to generic messages at the error handler layer; log full details server-side |
| Error monitoring noise | High volume of expected 4xx errors flooding Sentry/Bugsnag | Configure error monitoring to capture only 5xx; track 4xx via metrics, not error monitoring |
Refer to ${CLAUDE_SKILL_DIR}/references/errors.md for comprehensive error patterns.
RFC 7807 response: {"type":"https://api.example.com/errors/validation","title":"Validation Error","status":400,"detail":"Request body contains 2 validation errors","errors":[{"field":"email","message":"Invalid email format","code":"INVALID_FORMAT"}]}
Centralized Express error handler: Single app.use((err, req, res, next) => {...}) middleware that handles all error types, sets status codes, formats RFC 7807 bodies, logs with correlation ID, and reports to Sentry.
Graceful upstream failure: When a downstream payment service returns 500, wrap it in a ServiceUnavailableError with a user-friendly message, log the upstream response for debugging, and trigger a circuit breaker.
See ${CLAUDE_SKILL_DIR}/references/examples.md for additional examples.