import 'package:equatable/equatable.dart'; /// Classe de base abstraite pour toutes les erreurs de l'application. /// /// Les [Failure] représentent des erreurs métier qui peuvent être gérées /// de manière élégante par l'application, contrairement aux [Exception] /// qui sont des erreurs techniques. /// /// **Usage:** /// ```dart /// try { /// final result = await repository.getData(); /// return Right(result); /// } catch (e) { /// return Left(ServerFailure(message: e.toString())); /// } /// ``` abstract class Failure extends Equatable { /// Crée une nouvelle [Failure]. /// /// [message] Un message optionnel décrivant l'erreur /// [code] Un code d'erreur optionnel const Failure({ this.message = 'Une erreur est survenue', this.code, }); /// Message décrivant l'erreur final String message; /// Code d'erreur optionnel final String? code; @override List get props => [message, code]; @override String toString() => 'Failure(message: $message, code: $code)'; } /// Erreur liée au serveur ou à la communication réseau. /// /// Cette erreur est levée lorsque : /// - Une requête HTTP échoue /// - Le serveur retourne une erreur /// - La connexion réseau est perdue /// - Un timeout se produit /// /// **Exemple:** /// ```dart /// try { /// final response = await http.get(url); /// if (response.statusCode != 200) { /// throw ServerFailure( /// message: 'Erreur serveur: ${response.statusCode}', /// code: response.statusCode.toString(), /// ); /// } /// } catch (e) { /// throw ServerFailure(message: e.toString()); /// } /// ``` class ServerFailure extends Failure { /// Crée une nouvelle [ServerFailure]. /// /// [message] Message décrivant l'erreur serveur /// [code] Code d'erreur HTTP optionnel /// [statusCode] Code de statut HTTP optionnel const ServerFailure({ super.message = 'Erreur serveur', super.code, this.statusCode, }); /// Code de statut HTTP (404, 500, etc.) final int? statusCode; @override List get props => [...super.props, statusCode]; @override String toString() => 'ServerFailure(message: $message, code: $code, statusCode: $statusCode)'; } /// Erreur liée au cache local. /// /// Cette erreur est levée lorsque : /// - Les données ne peuvent pas être lues depuis le cache /// - Les données ne peuvent pas être écrites dans le cache /// - Le cache est corrompu ou inaccessible /// /// **Exemple:** /// ```dart /// try { /// final cachedData = await cache.get(key); /// if (cachedData == null) { /// throw CacheFailure(message: 'Données non trouvées dans le cache'); /// } /// } catch (e) { /// throw CacheFailure(message: e.toString()); /// } /// ``` class CacheFailure extends Failure { /// Crée une nouvelle [CacheFailure]. /// /// [message] Message décrivant l'erreur de cache /// [code] Code d'erreur optionnel const CacheFailure({ super.message = 'Erreur de cache', super.code, }); @override String toString() => 'CacheFailure(message: $message, code: $code)'; } /// Erreur liée à l'authentification. /// /// Cette erreur est levée lorsque : /// - Les identifiants sont incorrects /// - Le token d'authentification est expiré /// - L'utilisateur n'est pas autorisé /// /// **Exemple:** /// ```dart /// if (!isAuthenticated) { /// throw AuthenticationFailure( /// message: 'Authentification requise', /// ); /// } /// ``` class AuthenticationFailure extends Failure { /// Crée une nouvelle [AuthenticationFailure]. /// /// [message] Message décrivant l'erreur d'authentification /// [code] Code d'erreur optionnel const AuthenticationFailure({ super.message = 'Erreur d\'authentification', super.code, }); @override String toString() => 'AuthenticationFailure(message: $message, code: $code)'; } /// Erreur liée à la validation des données. /// /// Cette erreur est levée lorsque : /// - Les données saisies sont invalides /// - Les données ne respectent pas les contraintes /// - Les données sont manquantes /// /// **Exemple:** /// ```dart /// if (email.isEmpty || !isValidEmail(email)) { /// throw ValidationFailure( /// message: 'Email invalide', /// field: 'email', /// ); /// } /// ``` class ValidationFailure extends Failure { /// Crée une nouvelle [ValidationFailure]. /// /// [message] Message décrivant l'erreur de validation /// [field] Le champ qui a échoué la validation /// [code] Code d'erreur optionnel const ValidationFailure({ super.message = 'Erreur de validation', this.field, super.code, }); /// Le champ qui a échoué la validation final String? field; @override List get props => [super.props, field]; @override String toString() => 'ValidationFailure(message: $message, field: $field, code: $code)'; } /// Erreur liée à une opération réseau. /// /// Cette erreur est levée lorsque : /// - La connexion Internet est perdue /// - Le timeout est dépassé /// - La connexion est refusée /// /// **Exemple:** /// ```dart /// try { /// final response = await http.get(url).timeout( /// const Duration(seconds: 5), /// ); /// } on TimeoutException { /// throw NetworkFailure(message: 'Timeout de connexion'); /// } on SocketException { /// throw NetworkFailure(message: 'Pas de connexion Internet'); /// } /// ``` class NetworkFailure extends Failure { /// Crée une nouvelle [NetworkFailure]. /// /// [message] Message décrivant l'erreur réseau /// [code] Code d'erreur optionnel const NetworkFailure({ super.message = 'Erreur réseau', super.code, }); @override String toString() => 'NetworkFailure(message: $message, code: $code)'; }