- Renamed auth-service to iam-service across various files for consistency. - Updated Dockerfiles, deployment configurations, and documentation to reflect the service name change. - Enhanced testing commands in documentation to point to the new iam-service. - Removed outdated auth-service files and configurations to streamline the project structure. - Improved bilingual documentation for clarity on the new service structure and usage.
190 lines
5.1 KiB
TypeScript
190 lines
5.1 KiB
TypeScript
/**
|
|
* EN: Centralized error codes for consistent error handling
|
|
* VI: Error codes tập trung để xử lý lỗi nhất quán
|
|
*/
|
|
export enum ErrorCode {
|
|
// EN: Authentication & Authorization Errors
|
|
// VI: Lỗi Authentication & Authorization
|
|
UNAUTHORIZED = 'AUTH_001',
|
|
FORBIDDEN = 'AUTH_002',
|
|
INVALID_TOKEN = 'AUTH_003',
|
|
TOKEN_EXPIRED = 'AUTH_004',
|
|
MISSING_PERMISSIONS = 'AUTH_005',
|
|
|
|
// EN: Validation Errors
|
|
// VI: Lỗi Validation
|
|
VALIDATION_ERROR = 'VALIDATION_001',
|
|
INVALID_FORMAT = 'VALIDATION_002',
|
|
REQUIRED_FIELD = 'VALIDATION_003',
|
|
INVALID_VALUE = 'VALIDATION_004',
|
|
|
|
// EN: Resource Errors
|
|
// VI: Lỗi Resource
|
|
NOT_FOUND = 'RESOURCE_001',
|
|
ALREADY_EXISTS = 'RESOURCE_002',
|
|
CONFLICT = 'RESOURCE_003',
|
|
DELETED = 'RESOURCE_004',
|
|
|
|
// EN: Business Logic Errors
|
|
// VI: Lỗi Business Logic
|
|
INVALID_OPERATION = 'BUSINESS_001',
|
|
INSUFFICIENT_FUNDS = 'BUSINESS_002',
|
|
LIMIT_EXCEEDED = 'BUSINESS_003',
|
|
EXPIRED = 'BUSINESS_004',
|
|
|
|
// EN: External Service Errors
|
|
// VI: Lỗi External Service
|
|
EXTERNAL_SERVICE_ERROR = 'EXTERNAL_001',
|
|
SERVICE_UNAVAILABLE = 'EXTERNAL_002',
|
|
TIMEOUT = 'EXTERNAL_003',
|
|
NETWORK_ERROR = 'EXTERNAL_004',
|
|
|
|
// EN: Database Errors
|
|
// VI: Lỗi Database
|
|
DATABASE_ERROR = 'DB_001',
|
|
CONNECTION_ERROR = 'DB_002',
|
|
QUERY_ERROR = 'DB_003',
|
|
CONSTRAINT_VIOLATION = 'DB_004',
|
|
|
|
// EN: System Errors
|
|
// VI: Lỗi System
|
|
INTERNAL_ERROR = 'SYS_001',
|
|
CONFIGURATION_ERROR = 'SYS_002',
|
|
RATE_LIMIT_EXCEEDED = 'SYS_003',
|
|
MAINTENANCE_MODE = 'SYS_004',
|
|
|
|
// EN: Health Check Errors
|
|
// VI: Lỗi Health Check
|
|
HEALTH_CHECK_FAILED = 'HEALTH_001',
|
|
DATABASE_UNHEALTHY = 'HEALTH_002',
|
|
CACHE_UNHEALTHY = 'HEALTH_003',
|
|
EXTERNAL_DEPENDENCY_UNHEALTHY = 'HEALTH_004',
|
|
|
|
// EN: Feature-Specific Errors
|
|
// VI: Lỗi Feature-Specific
|
|
FEATURE_NOT_ENABLED = 'FEATURE_001',
|
|
FEATURE_CONFIG_INVALID = 'FEATURE_002',
|
|
FEATURE_DEPENDENCY_MISSING = 'FEATURE_003',
|
|
}
|
|
|
|
/**
|
|
* EN: Error code to HTTP status mapping
|
|
* VI: Mapping error code sang HTTP status
|
|
*/
|
|
export const ERROR_CODE_TO_STATUS: Record<ErrorCode, number> = {
|
|
// Auth errors
|
|
[ErrorCode.UNAUTHORIZED]: 401,
|
|
[ErrorCode.FORBIDDEN]: 403,
|
|
[ErrorCode.INVALID_TOKEN]: 401,
|
|
[ErrorCode.TOKEN_EXPIRED]: 401,
|
|
[ErrorCode.MISSING_PERMISSIONS]: 403,
|
|
|
|
// Validation errors
|
|
[ErrorCode.VALIDATION_ERROR]: 422,
|
|
[ErrorCode.INVALID_FORMAT]: 422,
|
|
[ErrorCode.REQUIRED_FIELD]: 422,
|
|
[ErrorCode.INVALID_VALUE]: 422,
|
|
|
|
// Resource errors
|
|
[ErrorCode.NOT_FOUND]: 404,
|
|
[ErrorCode.ALREADY_EXISTS]: 409,
|
|
[ErrorCode.CONFLICT]: 409,
|
|
[ErrorCode.DELETED]: 410,
|
|
|
|
// Business errors
|
|
[ErrorCode.INVALID_OPERATION]: 422,
|
|
[ErrorCode.INSUFFICIENT_FUNDS]: 422,
|
|
[ErrorCode.LIMIT_EXCEEDED]: 422,
|
|
[ErrorCode.EXPIRED]: 410,
|
|
|
|
// External service errors
|
|
[ErrorCode.EXTERNAL_SERVICE_ERROR]: 502,
|
|
[ErrorCode.SERVICE_UNAVAILABLE]: 503,
|
|
[ErrorCode.TIMEOUT]: 504,
|
|
[ErrorCode.NETWORK_ERROR]: 502,
|
|
|
|
// Database errors
|
|
[ErrorCode.DATABASE_ERROR]: 500,
|
|
[ErrorCode.CONNECTION_ERROR]: 503,
|
|
[ErrorCode.QUERY_ERROR]: 500,
|
|
[ErrorCode.CONSTRAINT_VIOLATION]: 422,
|
|
|
|
// System errors
|
|
[ErrorCode.INTERNAL_ERROR]: 500,
|
|
[ErrorCode.CONFIGURATION_ERROR]: 500,
|
|
[ErrorCode.RATE_LIMIT_EXCEEDED]: 429,
|
|
[ErrorCode.MAINTENANCE_MODE]: 503,
|
|
|
|
// Health errors
|
|
[ErrorCode.HEALTH_CHECK_FAILED]: 503,
|
|
[ErrorCode.DATABASE_UNHEALTHY]: 503,
|
|
[ErrorCode.CACHE_UNHEALTHY]: 503,
|
|
[ErrorCode.EXTERNAL_DEPENDENCY_UNHEALTHY]: 503,
|
|
|
|
// Feature errors
|
|
[ErrorCode.FEATURE_NOT_ENABLED]: 403,
|
|
[ErrorCode.FEATURE_CONFIG_INVALID]: 500,
|
|
[ErrorCode.FEATURE_DEPENDENCY_MISSING]: 500,
|
|
};
|
|
|
|
/**
|
|
* EN: Get HTTP status from error code
|
|
* VI: Lấy HTTP status từ error code
|
|
*/
|
|
export function getStatusFromErrorCode(errorCode: ErrorCode): number {
|
|
return ERROR_CODE_TO_STATUS[errorCode] || 500;
|
|
}
|
|
|
|
/**
|
|
* EN: Check if error code represents an operational error (not a programming error)
|
|
* VI: Kiểm tra error code có phải operational error (không phải programming error)
|
|
*/
|
|
export function isOperationalError(errorCode: ErrorCode): boolean {
|
|
const operationalCodes = [
|
|
// Auth errors
|
|
ErrorCode.UNAUTHORIZED,
|
|
ErrorCode.FORBIDDEN,
|
|
ErrorCode.INVALID_TOKEN,
|
|
ErrorCode.TOKEN_EXPIRED,
|
|
ErrorCode.MISSING_PERMISSIONS,
|
|
|
|
// Validation errors
|
|
ErrorCode.VALIDATION_ERROR,
|
|
ErrorCode.INVALID_FORMAT,
|
|
ErrorCode.REQUIRED_FIELD,
|
|
ErrorCode.INVALID_VALUE,
|
|
|
|
// Resource errors
|
|
ErrorCode.NOT_FOUND,
|
|
ErrorCode.ALREADY_EXISTS,
|
|
ErrorCode.CONFLICT,
|
|
ErrorCode.DELETED,
|
|
|
|
// Business errors
|
|
ErrorCode.INVALID_OPERATION,
|
|
ErrorCode.INSUFFICIENT_FUNDS,
|
|
ErrorCode.LIMIT_EXCEEDED,
|
|
ErrorCode.EXPIRED,
|
|
|
|
// External service errors
|
|
ErrorCode.EXTERNAL_SERVICE_ERROR,
|
|
ErrorCode.SERVICE_UNAVAILABLE,
|
|
ErrorCode.TIMEOUT,
|
|
ErrorCode.NETWORK_ERROR,
|
|
|
|
// System errors
|
|
ErrorCode.RATE_LIMIT_EXCEEDED,
|
|
ErrorCode.MAINTENANCE_MODE,
|
|
|
|
// Health errors
|
|
ErrorCode.HEALTH_CHECK_FAILED,
|
|
ErrorCode.DATABASE_UNHEALTHY,
|
|
ErrorCode.CACHE_UNHEALTHY,
|
|
ErrorCode.EXTERNAL_DEPENDENCY_UNHEALTHY,
|
|
|
|
// Feature errors
|
|
ErrorCode.FEATURE_NOT_ENABLED,
|
|
];
|
|
|
|
return operationalCodes.includes(errorCode);
|
|
} |