Files
goodgo-platform/apps/api/src/modules/shared/domain/error-codes.ts
Ho Ngoc Hai 54c97daa5b fix(auth): migrate raw Error throws to DomainException (GOO-52)
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>
2026-04-23 19:58:31 +07:00

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',
}