Error Handling¶
dichit-backend uses typed custom errors mapped centrally to HTTP responses. Errors are defined in src/shared/errors and mapped by the error-handler plugin (src/infrastructure/plugins/03-error-handler.ts).
Error model¶
flowchart LR
E["Throw typed error (use case / service)"] --> M["error-handler plugin"]
M -->|"UnprocessableEntityError"| 422
M -->|"NotFoundError"| 404
M -->|"UnauthorizedError"| 401
M -->|"ForbiddenError"| 403
M -->|"ConflictError"| 409
M -->|"unexpected"| 500 Rules¶
- Reuse
src/shared/errorsbefore creating new error shapes. - Throw typed errors in application/infrastructure code; let the plugin map them.
- Never expose stack traces or internal messages in responses.
- Keep error responses stable for clients (see the Swagger error schemas in
src/shared/swagger-schemas/general). - Do not leak whether an unauthorized record exists (see authorization.md).
allowErrorHandlerOverride: trueis set on Fastify so Sentry/error handler wiring composes (see monitoring).
Response shape¶
Typed errors serialize to a consistent shape. Example:
Error handling in WebSocket¶
WS errors use their own envelope and codes (e.g. FORBIDDEN, RATE_LIMITED), defined in api/websocket/errors.md.
Logging¶
- Log failures with enough context (correlation id, operation) to debug.
- Never log secrets, OTPs, tokens, or full auth headers.
- Unexpected errors reach Sentry automatically (see infrastructure/monitoring.md).
Best practices checklist¶
- Throw the most specific typed error available
- No
console.errorin use cases — use the logger with request context - Validate input before DB operations (see validation.md)
- Wrap provider errors into typed errors at the infrastructure boundary
- Add tests for the error cases (see testing.md)