/// Failure classes for error handling in the Worker app /// /// Failures represent domain-level errors that can be returned from use cases /// and repositories. They wrap exceptions and provide user-friendly error messages. library; /// Base failure class sealed class Failure { const Failure({required this.message}); /// Network-related failure const factory Failure.network({ required String message, int? statusCode, }) = NetworkFailure; /// Server error failure (5xx errors) const factory Failure.server({ required String message, int? statusCode, }) = ServerFailure; /// Authentication failure const factory Failure.authentication({ required String message, int? statusCode, }) = AuthenticationFailure; /// Validation failure const factory Failure.validation({ required String message, Map>? errors, }) = ValidationFailure; /// Not found failure (404) const factory Failure.notFound({ required String message, }) = NotFoundFailure; /// Conflict failure (409) const factory Failure.conflict({ required String message, }) = ConflictFailure; /// Rate limit exceeded failure (429) const factory Failure.rateLimit({ required String message, int? retryAfter, }) = RateLimitFailure; /// Payment failure const factory Failure.payment({ required String message, String? transactionId, }) = PaymentFailure; /// Cache failure const factory Failure.cache({ required String message, }) = CacheFailure; /// Storage failure const factory Failure.storage({ required String message, }) = StorageFailure; /// Parse failure const factory Failure.parse({ required String message, }) = ParseFailure; /// No internet connection failure const factory Failure.noInternet() = NoInternetFailure; /// Timeout failure const factory Failure.timeout() = TimeoutFailure; /// Unknown failure const factory Failure.unknown({ required String message, }) = UnknownFailure; final String message; /// Check if this is a critical failure that requires immediate attention bool get isCritical { return switch (this) { ServerFailure() => true, AuthenticationFailure() => true, PaymentFailure() => true, UnknownFailure() => true, _ => false, }; } /// Check if this failure can be retried bool get canRetry { return switch (this) { NetworkFailure() => true, ServerFailure(:final statusCode) => statusCode == 503, AuthenticationFailure(:final statusCode) => statusCode == 401, RateLimitFailure() => true, CacheFailure() => true, NoInternetFailure() => true, TimeoutFailure() => true, _ => false, }; } /// Get HTTP status code if available int? get statusCode { return switch (this) { NetworkFailure(:final statusCode) => statusCode, ServerFailure(:final statusCode) => statusCode, AuthenticationFailure(:final statusCode) => statusCode, _ => null, }; } /// Get user-friendly error message String getUserMessage() { return switch (this) { ValidationFailure(:final message, :final errors) => _formatValidationMessage(message, errors), RateLimitFailure(:final message, :final retryAfter) => _formatRateLimitMessage(message, retryAfter), NoInternetFailure() => 'Không có kết nối internet. Vui lòng kiểm tra kết nối của bạn.', TimeoutFailure() => 'Kết nối quá lâu. Vui lòng thử lại.', _ => message, }; } String _formatValidationMessage(String message, Map>? errors) { if (errors != null && errors.isNotEmpty) { final firstError = errors.values.first.first; return '$message: $firstError'; } return message; } String _formatRateLimitMessage(String message, int? retryAfter) { if (retryAfter != null) { return '$message Thử lại sau $retryAfter giây.'; } return message; } } /// Network-related failure final class NetworkFailure extends Failure { const NetworkFailure({ required super.message, this.statusCode, }); @override final int? statusCode; } /// Server error failure (5xx errors) final class ServerFailure extends Failure { const ServerFailure({ required super.message, this.statusCode, }); @override final int? statusCode; } /// Authentication failure final class AuthenticationFailure extends Failure { const AuthenticationFailure({ required super.message, this.statusCode, }); @override final int? statusCode; } /// Validation failure final class ValidationFailure extends Failure { const ValidationFailure({ required super.message, this.errors, }); final Map>? errors; } /// Not found failure (404) final class NotFoundFailure extends Failure { const NotFoundFailure({ required super.message, }); } /// Conflict failure (409) final class ConflictFailure extends Failure { const ConflictFailure({ required super.message, }); } /// Rate limit exceeded failure (429) final class RateLimitFailure extends Failure { const RateLimitFailure({ required super.message, this.retryAfter, }); final int? retryAfter; } /// Payment failure final class PaymentFailure extends Failure { const PaymentFailure({ required super.message, this.transactionId, }); final String? transactionId; } /// Cache failure final class CacheFailure extends Failure { const CacheFailure({ required super.message, }); } /// Storage failure final class StorageFailure extends Failure { const StorageFailure({ required super.message, }); } /// Parse failure final class ParseFailure extends Failure { const ParseFailure({ required super.message, }); } /// No internet connection failure final class NoInternetFailure extends Failure { const NoInternetFailure() : super(message: 'Không có kết nối internet'); } /// Timeout failure final class TimeoutFailure extends Failure { const TimeoutFailure() : super(message: 'Kết nối quá lâu'); } /// Unknown failure final class UnknownFailure extends Failure { const UnknownFailure({ required super.message, }); }