feat(shared): add error handling & structured logging strategy

- Global exception filter with consistent error response format
- Domain exceptions (NotFoundException, ValidationException, etc.)
- Error codes enum for domain-specific error identification
- Correlation ID middleware for request tracing
- Request/response logging middleware with structured JSON
- PII masking in logs (emails, phone numbers, sensitive fields)
- Enhanced LoggerService with pino formatters and ISO timestamps
- Tests for exception filter, domain exceptions, and PII masker

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Ho Ngoc Hai
2026-04-08 00:18:21 +07:00
parent 1fb7bb39d2
commit c981bff771
14 changed files with 564 additions and 5 deletions

View File

@@ -0,0 +1,36 @@
/**
* Domain-specific error codes for consistent error identification across the platform.
* Format: DOMAIN_ACTION_REASON
*/
export enum ErrorCode {
// General
INTERNAL_ERROR = 'INTERNAL_ERROR',
VALIDATION_FAILED = 'VALIDATION_FAILED',
NOT_FOUND = 'NOT_FOUND',
CONFLICT = 'CONFLICT',
UNAUTHORIZED = 'UNAUTHORIZED',
FORBIDDEN = 'FORBIDDEN',
BAD_REQUEST = 'BAD_REQUEST',
TOO_MANY_REQUESTS = 'TOO_MANY_REQUESTS',
// Auth
AUTH_INVALID_CREDENTIALS = 'AUTH_INVALID_CREDENTIALS',
AUTH_TOKEN_EXPIRED = 'AUTH_TOKEN_EXPIRED',
AUTH_TOKEN_INVALID = 'AUTH_TOKEN_INVALID',
AUTH_INSUFFICIENT_PERMISSIONS = 'AUTH_INSUFFICIENT_PERMISSIONS',
// User
USER_NOT_FOUND = 'USER_NOT_FOUND',
USER_ALREADY_EXISTS = 'USER_ALREADY_EXISTS',
USER_INVALID_PHONE = 'USER_INVALID_PHONE',
// Course
COURSE_NOT_FOUND = 'COURSE_NOT_FOUND',
COURSE_ALREADY_PUBLISHED = 'COURSE_ALREADY_PUBLISHED',
COURSE_ENROLLMENT_CLOSED = 'COURSE_ENROLLMENT_CLOSED',
// Payment
PAYMENT_FAILED = 'PAYMENT_FAILED',
PAYMENT_ALREADY_PROCESSED = 'PAYMENT_ALREADY_PROCESSED',
PAYMENT_INVALID_AMOUNT = 'PAYMENT_INVALID_AMOUNT',
}