/// 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'; } }