/// Custom exceptions for the Worker app /// /// This file defines all custom exception types used throughout the application /// for better error handling and user feedback. library; // ============================================================================ // Network Exceptions // ============================================================================ /// Base exception for all network-related errors class NetworkException implements Exception { const NetworkException( this.message, { this.statusCode, this.data, }); final String message; final int? statusCode; final dynamic data; @override String toString() => 'NetworkException: $message${statusCode != null ? ' (Status: $statusCode)' : ''}'; } /// Exception thrown when there's no internet connection class NoInternetException extends NetworkException { const NoInternetException() : super( 'Không có kết nối internet. Vui lòng kiểm tra kết nối của bạn.', ); } /// Exception thrown when connection times out class TimeoutException extends NetworkException { const TimeoutException() : super( 'Kết nối quá lâu. Vui lòng thử lại.', statusCode: 408, ); } /// Exception thrown when server returns 500+ errors class ServerException extends NetworkException { const ServerException([ String message = 'Lỗi máy chủ. Vui lòng thử lại sau.', int? statusCode, ]) : super(message, statusCode: statusCode); } /// Exception thrown when server is unreachable class ServiceUnavailableException extends ServerException { const ServiceUnavailableException() : super( 'Dịch vụ tạm thời không khả dụng. Vui lòng thử lại sau.', 503, ); } // ============================================================================ // Authentication Exceptions // ============================================================================ /// Base exception for authentication-related errors class AuthException implements Exception { const AuthException( this.message, { this.statusCode, }); final String message; final int? statusCode; @override String toString() => 'AuthException: $message'; } /// Exception thrown when authentication credentials are invalid class InvalidCredentialsException extends AuthException { const InvalidCredentialsException() : super( 'Thông tin đăng nhập không hợp lệ.', statusCode: 401, ); } /// Exception thrown when user is not authenticated class UnauthorizedException extends AuthException { const UnauthorizedException([ super.message = 'Phiên đăng nhập hết hạn. Vui lòng đăng nhập lại.', ]) : super(statusCode: 401); } /// Exception thrown when user doesn't have permission class ForbiddenException extends AuthException { const ForbiddenException() : super( 'Bạn không có quyền truy cập tài nguyên này.', statusCode: 403, ); } /// Exception thrown when auth token is expired class TokenExpiredException extends AuthException { const TokenExpiredException() : super( 'Phiên đăng nhập hết hạn. Vui lòng đăng nhập lại.', statusCode: 401, ); } /// Exception thrown when refresh token is invalid class InvalidRefreshTokenException extends AuthException { const InvalidRefreshTokenException() : super( 'Không thể làm mới phiên đăng nhập. Vui lòng đăng nhập lại.', statusCode: 401, ); } /// Exception thrown when OTP is invalid class InvalidOTPException extends AuthException { const InvalidOTPException() : super( 'Mã OTP không hợp lệ. Vui lòng thử lại.', statusCode: 400, ); } /// Exception thrown when OTP is expired class OTPExpiredException extends AuthException { const OTPExpiredException() : super( 'Mã OTP đã hết hạn. Vui lòng yêu cầu mã mới.', statusCode: 400, ); } // ============================================================================ // Request Validation Exceptions // ============================================================================ /// Exception thrown when request data is invalid class ValidationException implements Exception { const ValidationException( this.message, { this.errors, }); final String message; final Map>? errors; @override String toString() { if (errors != null && errors!.isNotEmpty) { final errorMessages = errors!.entries .map((e) => '${e.key}: ${e.value.join(", ")}') .join('; '); return 'ValidationException: $message - $errorMessages'; } return 'ValidationException: $message'; } } /// Exception thrown when request parameters are invalid class BadRequestException extends ValidationException { const BadRequestException([ String message = 'Yêu cầu không hợp lệ.', Map>? errors, ]) : super(message, errors: errors); } // ============================================================================ // Resource Exceptions // ============================================================================ /// Exception thrown when requested resource is not found class NotFoundException implements Exception { const NotFoundException([ this.message = 'Không tìm thấy tài nguyên.', this.resourceType, this.resourceId, ]); final String message; final String? resourceType; final String? resourceId; @override String toString() { if (resourceType != null && resourceId != null) { return 'NotFoundException: $resourceType with ID $resourceId not found'; } return 'NotFoundException: $message'; } } /// Exception thrown when trying to create a duplicate resource class ConflictException implements Exception { const ConflictException([ this.message = 'Tài nguyên đã tồn tại.', ]); final String message; @override String toString() => 'ConflictException: $message'; } // ============================================================================ // Rate Limiting Exceptions // ============================================================================ /// Exception thrown when API rate limit is exceeded class RateLimitException implements Exception { const RateLimitException([ this.message = 'Bạn đã gửi quá nhiều yêu cầu. Vui lòng thử lại sau.', this.retryAfter, ]); final String message; final int? retryAfter; // seconds @override String toString() { if (retryAfter != null) { return 'RateLimitException: $message (Retry after: ${retryAfter}s)'; } return 'RateLimitException: $message'; } } // ============================================================================ // Payment Exceptions // ============================================================================ /// Exception thrown for payment-related errors class PaymentException implements Exception { const PaymentException( this.message, { this.transactionId, }); final String message; final String? transactionId; @override String toString() => 'PaymentException: $message'; } /// Exception thrown when payment fails class PaymentFailedException extends PaymentException { const PaymentFailedException([ String message = 'Thanh toán thất bại. Vui lòng thử lại.', String? transactionId, ]) : super(message, transactionId: transactionId); } /// Exception thrown when payment is cancelled class PaymentCancelledException extends PaymentException { const PaymentCancelledException() : super('Thanh toán đã bị hủy.'); } // ============================================================================ // Cache Exceptions // ============================================================================ /// Exception thrown for cache-related errors class CacheException implements Exception { const CacheException([ this.message = 'Lỗi khi truy cập bộ nhớ đệm.', ]); final String message; @override String toString() => 'CacheException: $message'; } /// Exception thrown when cache data is corrupted class CacheCorruptedException extends CacheException { const CacheCorruptedException() : super('Dữ liệu bộ nhớ đệm bị hỏng.'); } // ============================================================================ // Storage Exceptions // ============================================================================ /// Exception thrown for local storage errors class StorageException implements Exception { const StorageException([ this.message = 'Lỗi khi truy cập bộ nhớ cục bộ.', ]); final String message; @override String toString() => 'StorageException: $message'; } /// Exception thrown when storage is full class StorageFullException extends StorageException { const StorageFullException() : super('Bộ nhớ đã đầy. Vui lòng giải phóng không gian.'); } // ============================================================================ // Parse Exceptions // ============================================================================ /// Exception thrown when JSON parsing fails class ParseException implements Exception { const ParseException([ this.message = 'Lỗi khi phân tích dữ liệu.', this.source, ]); final String message; final dynamic source; @override String toString() => 'ParseException: $message'; } // ============================================================================ // Unknown Exceptions // ============================================================================ /// Exception thrown for unexpected errors class UnknownException implements Exception { const UnknownException([ this.message = 'Đã xảy ra lỗi không xác định.', this.originalError, this.stackTrace, ]); final String message; final dynamic originalError; final StackTrace? stackTrace; @override String toString() { if (originalError != null) { return 'UnknownException: $message (Original: $originalError)'; } return 'UnknownException: $message'; } }