feat(mobile): amélioration gestion erreurs LCB-FT (T021)

Phase 4 Mobile - Section 4.1 Épargne

Nouveau fichier :
- ErrorFormatter : utilitaire central pour formater les erreurs backend
  - Détecte et formate spécialement les erreurs LCB-FT (origine fonds manquante)
  - Détecte erreurs KYC, réseau, 400/401/403/404/500
  - Messages conviviaux avec emojis
  - Durée d'affichage adaptée (6s pour LCB-FT, 3s sinon)

Modifications 3 dialogs (dépôt, retrait, transfert) :
- Remplacement affichage erreur brut par ErrorFormatter.format()
- Messages explicites : "L'origine des fonds est obligatoire (conformité LCB-FT)"
- Durée snackbar conditionnelle selon type erreur

Impact UX :
- Messages d'erreur clairs et professionnels
- Utilisateur comprend POURQUOI l'origine fonds est requise (anti-blanchiment)
- Temps de lecture suffisant pour messages importants

Spec : specs/001-mutuelles-anti-blanchiment/spec.md
Progression : 18/27 tâches (67%)

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 02:46:41 +00:00
parent 5ef8ae1140
commit 62318476f8
4 changed files with 114 additions and 5 deletions

View File

@@ -4,6 +4,7 @@ import 'package:url_launcher/url_launcher.dart';
import '../../../../core/constants/lcb_ft_constants.dart';
import '../../../../core/data/repositories/parametres_lcb_ft_repository.dart';
import '../../../../core/utils/error_formatter.dart';
import '../../data/models/transaction_epargne_request.dart';
import '../../data/repositories/transaction_epargne_repository.dart';
@@ -113,7 +114,10 @@ class _DepotEpargneDialogState extends State<DepotEpargneDialog> {
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Wave: ${e.toString().replaceFirst('Exception: ', '')}')),
SnackBar(
content: Text(ErrorFormatter.format(e)),
duration: ErrorFormatter.isLcbFtError(e) ? const Duration(seconds: 6) : const Duration(seconds: 3),
),
);
} finally {
if (mounted) setState(() => _waveLoading = false);
@@ -158,7 +162,10 @@ class _DepotEpargneDialogState extends State<DepotEpargneDialog> {
} catch (e) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Erreur: $e')),
SnackBar(
content: Text(ErrorFormatter.format(e)),
duration: ErrorFormatter.isLcbFtError(e) ? const Duration(seconds: 6) : const Duration(seconds: 3),
),
);
} finally {
if (mounted) setState(() => _loading = false);

View File

@@ -3,6 +3,7 @@ import 'package:get_it/get_it.dart';
import '../../../../core/constants/lcb_ft_constants.dart';
import '../../../../core/data/repositories/parametres_lcb_ft_repository.dart';
import '../../../../core/utils/error_formatter.dart';
import '../../data/models/transaction_epargne_request.dart';
import '../../data/repositories/transaction_epargne_repository.dart';
import '../../../../shared/design_system/unionflow_design_system.dart';
@@ -105,17 +106,21 @@ class _RetraitEpargneDialogState extends State<RetraitEpargneDialog> {
_showSnack('Retrait enregistré', isError: false);
} catch (e) {
if (!mounted) return;
_showSnack('Erreur: ${e.toString().replaceFirst('Exception: ', '')}');
_showSnack(
ErrorFormatter.format(e),
duration: ErrorFormatter.isLcbFtError(e) ? 6 : 3,
);
} finally {
if (mounted) setState(() => _loading = false);
}
}
void _showSnack(String msg, {bool isError = true}) {
void _showSnack(String msg, {bool isError = true, int duration = 3}) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(msg),
backgroundColor: isError ? ColorTokens.error : ColorTokens.success,
duration: Duration(seconds: duration),
),
);
}

View File

@@ -3,6 +3,7 @@ import 'package:get_it/get_it.dart';
import '../../../../core/constants/lcb_ft_constants.dart';
import '../../../../core/data/repositories/parametres_lcb_ft_repository.dart';
import '../../../../core/utils/error_formatter.dart';
import '../../data/models/compte_epargne_model.dart';
import '../../data/models/transaction_epargne_request.dart';
import '../../data/repositories/transaction_epargne_repository.dart';
@@ -130,8 +131,9 @@ class _TransfertEpargneDialogState extends State<TransfertEpargneDialog> {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Erreur: ${e.toString().replaceFirst('Exception: ', '')}'),
content: Text(ErrorFormatter.format(e)),
backgroundColor: ColorTokens.error,
duration: ErrorFormatter.isLcbFtError(e) ? const Duration(seconds: 6) : const Duration(seconds: 3),
),
);
} finally {