219 lines
6.0 KiB
Dart
219 lines
6.0 KiB
Dart
/// 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<String, List<String>>? 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<String, List<String>>? 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<String, List<String>>? 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});
|
|
}
|