Replace 9 raw `throw new Error(...)` instances in the auth module with typed DomainException subclasses so the GlobalExceptionFilter produces structured error responses with proper HTTP status codes and error codes. - zalo-oauth.strategy.ts (4): AUTH_OAUTH_PROVIDER_ERROR / 502 - jwt.strategy.ts (1): AUTH_CONFIG_MISSING / 500 - auth.module.ts (1): AUTH_CONFIG_MISSING / 500 - oauth.service.ts (3): AUTH_ACCOUNT_DISABLED / 403 - Add AUTH_OAUTH_PROVIDER_ERROR, AUTH_CONFIG_MISSING, AUTH_ACCOUNT_DISABLED to ErrorCode enum - Update jwt.strategy.spec.ts mock to export DomainException + ErrorCode Co-Authored-By: Paperclip <noreply@paperclip.ing>
85 lines
2.9 KiB
TypeScript
85 lines
2.9 KiB
TypeScript
/**
|
|
* 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',
|
|
AUTH_OAUTH_PROVIDER_ERROR = 'AUTH_OAUTH_PROVIDER_ERROR',
|
|
AUTH_CONFIG_MISSING = 'AUTH_CONFIG_MISSING',
|
|
AUTH_ACCOUNT_DISABLED = 'AUTH_ACCOUNT_DISABLED',
|
|
|
|
// 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',
|
|
|
|
// Listing
|
|
LISTING_NOT_FOUND = 'LISTING_NOT_FOUND',
|
|
LISTING_INVALID_STATUS_TRANSITION = 'LISTING_INVALID_STATUS_TRANSITION',
|
|
LISTING_ALREADY_ACTIVE = 'LISTING_ALREADY_ACTIVE',
|
|
LISTING_EXPIRED = 'LISTING_EXPIRED',
|
|
|
|
// Property
|
|
PROPERTY_NOT_FOUND = 'PROPERTY_NOT_FOUND',
|
|
|
|
// Project (residential development)
|
|
PROJECT_NOT_FOUND = 'PROJECT_NOT_FOUND',
|
|
|
|
// Media
|
|
MEDIA_UPLOAD_FAILED = 'MEDIA_UPLOAD_FAILED',
|
|
MEDIA_LIMIT_EXCEEDED = 'MEDIA_LIMIT_EXCEEDED',
|
|
|
|
// Payment
|
|
PAYMENT_FAILED = 'PAYMENT_FAILED',
|
|
PAYMENT_ALREADY_PROCESSED = 'PAYMENT_ALREADY_PROCESSED',
|
|
PAYMENT_INVALID_AMOUNT = 'PAYMENT_INVALID_AMOUNT',
|
|
|
|
// Order
|
|
ORDER_NOT_FOUND = 'ORDER_NOT_FOUND',
|
|
ORDER_INVALID_STATUS_TRANSITION = 'ORDER_INVALID_STATUS_TRANSITION',
|
|
ORDER_ALREADY_EXISTS = 'ORDER_ALREADY_EXISTS',
|
|
|
|
// Escrow
|
|
ESCROW_NOT_FOUND = 'ESCROW_NOT_FOUND',
|
|
ESCROW_INVALID_STATE = 'ESCROW_INVALID_STATE',
|
|
|
|
// Subscription
|
|
SUBSCRIPTION_NOT_FOUND = 'SUBSCRIPTION_NOT_FOUND',
|
|
SUBSCRIPTION_ALREADY_ACTIVE = 'SUBSCRIPTION_ALREADY_ACTIVE',
|
|
SUBSCRIPTION_ALREADY_CANCELLED = 'SUBSCRIPTION_ALREADY_CANCELLED',
|
|
SUBSCRIPTION_INACTIVE = 'SUBSCRIPTION_INACTIVE',
|
|
QUOTA_EXCEEDED = 'QUOTA_EXCEEDED',
|
|
|
|
// AI / Claude integration
|
|
AI_NOT_CONFIGURED = 'AI_NOT_CONFIGURED',
|
|
AI_PROVIDER_ERROR = 'AI_PROVIDER_ERROR',
|
|
|
|
// Notifications
|
|
NOTIFICATION_TEMPLATE_NOT_FOUND = 'NOTIFICATION_TEMPLATE_NOT_FOUND',
|
|
NOTIFICATION_PROVIDER_NOT_CONFIGURED = 'NOTIFICATION_PROVIDER_NOT_CONFIGURED',
|
|
NOTIFICATION_PROVIDER_ERROR = 'NOTIFICATION_PROVIDER_ERROR',
|
|
NOTIFICATION_INVALID_TOKEN = 'NOTIFICATION_INVALID_TOKEN',
|
|
NOTIFICATION_INTERACTION_WINDOW_EXPIRED = 'NOTIFICATION_INTERACTION_WINDOW_EXPIRED',
|
|
NOTIFICATION_LINK_NOT_FOUND = 'NOTIFICATION_LINK_NOT_FOUND',
|
|
NOTIFICATION_OAUTH_INVALID_STATE = 'NOTIFICATION_OAUTH_INVALID_STATE',
|
|
}
|