feat: Implement centralized error handling with ErrorService; replace print statements with logging in services and blocs
feat: Add ErrorContent widget for displaying error messages in dialogs and bottom sheets refactor: Update GroupBloc and GroupRepository to utilize ErrorService for error logging refactor: Enhance user and trip services to log errors using ErrorService refactor: Clean up debug print statements in GroupContent and related components
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:travel_mate/components/error/error_content.dart';
|
||||
import '../../blocs/user/user_bloc.dart';
|
||||
import '../../blocs/user/user_state.dart' as user_state;
|
||||
import '../../blocs/group/group_bloc.dart';
|
||||
@@ -18,55 +19,39 @@ class _GroupContentState extends State<GroupContent> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
print('===== GroupContent: initState =====');
|
||||
|
||||
// Charger immédiatement sans attendre le prochain frame
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
print('===== PostFrameCallback déclenché =====');
|
||||
_loadInitialData();
|
||||
});
|
||||
}
|
||||
|
||||
void _loadInitialData() {
|
||||
print('===== _loadInitialData START =====');
|
||||
try {
|
||||
final userState = context.read<UserBloc>().state;
|
||||
print('UserBloc state type: ${userState.runtimeType}');
|
||||
print('UserBloc state: $userState');
|
||||
|
||||
if (userState is user_state.UserLoaded) {
|
||||
final userId = userState.user.id;
|
||||
print('✓ User chargé, ID: $userId');
|
||||
print('>>> Envoi de LoadGroupsByUserId <<<');
|
||||
context.read<GroupBloc>().add(LoadGroupsByUserId(userId));
|
||||
print('>>> LoadGroupsByUserId envoyé <<<');
|
||||
} else {
|
||||
print('✗ UserState n\'est pas UserLoaded');
|
||||
throw Exception('Utilisateur non connecté');
|
||||
}
|
||||
} catch (e, stackTrace) {
|
||||
print('===== ERREUR _loadInitialData =====');
|
||||
print('Exception: $e');
|
||||
print('StackTrace: $stackTrace');
|
||||
} catch (e) {
|
||||
_buildErrorState(e.toString(), '', true);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
print('===== GroupContent: build =====');
|
||||
|
||||
return BlocBuilder<UserBloc, user_state.UserState>(
|
||||
builder: (context, userState) {
|
||||
print('>>> UserBloc builder - state type: ${userState.runtimeType}');
|
||||
|
||||
if (userState is user_state.UserLoading) {
|
||||
print('État: UserLoading');
|
||||
return const Scaffold(
|
||||
body: Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
|
||||
if (userState is user_state.UserError) {
|
||||
print('État: UserError - ${userState.message}');
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
@@ -82,23 +67,15 @@ class _GroupContentState extends State<GroupContent> {
|
||||
}
|
||||
|
||||
if (userState is! user_state.UserLoaded) {
|
||||
print('État: Utilisateur non connecté');
|
||||
return const Scaffold(
|
||||
body: Center(child: Text('Utilisateur non connecté')),
|
||||
);
|
||||
}
|
||||
|
||||
print('✓ État: UserLoaded');
|
||||
final user = userState.user;
|
||||
|
||||
return BlocConsumer<GroupBloc, GroupState>(
|
||||
listener: (context, groupState) {
|
||||
print('===== GroupBloc LISTENER =====');
|
||||
print('State type: ${groupState.runtimeType}');
|
||||
print('State: $groupState');
|
||||
|
||||
if (groupState is GroupOperationSuccess) {
|
||||
print('>>> GroupOperationSuccess: ${groupState.message}');
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(groupState.message),
|
||||
@@ -106,7 +83,6 @@ class _GroupContentState extends State<GroupContent> {
|
||||
),
|
||||
);
|
||||
} else if (groupState is GroupError) {
|
||||
print('>>> GroupError: ${groupState.message}');
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(groupState.message),
|
||||
@@ -116,19 +92,6 @@ class _GroupContentState extends State<GroupContent> {
|
||||
}
|
||||
},
|
||||
builder: (context, groupState) {
|
||||
print('===== GroupBloc BUILDER =====');
|
||||
print('State type: ${groupState.runtimeType}');
|
||||
print('State: $groupState');
|
||||
|
||||
// TEST: Afficher le type exact
|
||||
if (groupState is GroupsLoaded) {
|
||||
print('✓✓✓ GroupsLoaded détecté ! ✓✓✓');
|
||||
print('Nombre de groupes: ${groupState.groups.length}');
|
||||
for (var i = 0; i < groupState.groups.length; i++) {
|
||||
print(' Groupe $i: ${groupState.groups[i].name}');
|
||||
}
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: _buildContent(groupState, user.id),
|
||||
@@ -141,11 +104,7 @@ class _GroupContentState extends State<GroupContent> {
|
||||
}
|
||||
|
||||
Widget _buildContent(GroupState groupState, String userId) {
|
||||
print('===== _buildContent =====');
|
||||
print('State type: ${groupState.runtimeType}');
|
||||
|
||||
if (groupState is GroupLoading) {
|
||||
print('>>> Affichage: Loading');
|
||||
return const Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -159,24 +118,18 @@ class _GroupContentState extends State<GroupContent> {
|
||||
}
|
||||
|
||||
if (groupState is GroupError) {
|
||||
print('>>> Affichage: Error');
|
||||
return _buildErrorState(groupState.message, userId);
|
||||
return _buildErrorState(groupState.message, userId, true);
|
||||
}
|
||||
|
||||
if (groupState is GroupsLoaded) {
|
||||
print('>>> Affichage: GroupsLoaded');
|
||||
print('Groupes: ${groupState.groups.length}');
|
||||
|
||||
if (groupState.groups.isEmpty) {
|
||||
print('>>> Affichage: Empty');
|
||||
return _buildEmptyState();
|
||||
}
|
||||
|
||||
print('>>> Affichage: Liste des groupes');
|
||||
return _buildGroupsList(groupState.groups, userId);
|
||||
}
|
||||
|
||||
print('>>> Affichage: Initial/Unknown');
|
||||
return Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -185,7 +138,6 @@ class _GroupContentState extends State<GroupContent> {
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
print('>>> Bouton refresh cliqué');
|
||||
context.read<GroupBloc>().add(LoadGroupsByUserId(userId));
|
||||
},
|
||||
child: const Text('Charger les groupes'),
|
||||
@@ -196,12 +148,8 @@ class _GroupContentState extends State<GroupContent> {
|
||||
}
|
||||
|
||||
Widget _buildGroupsList(List<Group> groups, String userId) {
|
||||
print('===== _buildGroupsList =====');
|
||||
print('Nombre de groupes à afficher: ${groups.length}');
|
||||
|
||||
return RefreshIndicator(
|
||||
onRefresh: () async {
|
||||
print('>>> Pull to refresh');
|
||||
context.read<GroupBloc>().add(LoadGroupsByUserId(userId));
|
||||
await Future.delayed(const Duration(milliseconds: 500));
|
||||
},
|
||||
@@ -221,20 +169,17 @@ class _GroupContentState extends State<GroupContent> {
|
||||
|
||||
// IMPORTANT: Utiliser un simple Column au lieu de GridView pour tester
|
||||
...groups.map((group) {
|
||||
print('Création widget pour: ${group.name}');
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12),
|
||||
child: _buildSimpleGroupCard(group),
|
||||
);
|
||||
}).toList(),
|
||||
})
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSimpleGroupCard(Group group) {
|
||||
print('===== _buildSimpleGroupCard: ${group.name} =====');
|
||||
|
||||
try {
|
||||
final colors = [Colors.blue, Colors.purple, Colors.green, Colors.orange];
|
||||
final color = colors[group.name.hashCode.abs() % colors.length];
|
||||
@@ -248,8 +193,6 @@ class _GroupContentState extends State<GroupContent> {
|
||||
.join(', ');
|
||||
memberInfo += '\n$names';
|
||||
}
|
||||
|
||||
print('Card créée avec succès');
|
||||
|
||||
return Card(
|
||||
elevation: 2,
|
||||
@@ -265,14 +208,11 @@ class _GroupContentState extends State<GroupContent> {
|
||||
subtitle: Text(memberInfo),
|
||||
trailing: const Icon(Icons.chevron_right),
|
||||
onTap: () {
|
||||
print('Tap sur: ${group.name}');
|
||||
_openGroupChat(group);
|
||||
},
|
||||
),
|
||||
);
|
||||
} catch (e, stackTrace) {
|
||||
print('ERREUR dans _buildSimpleGroupCard: $e');
|
||||
print('StackTrace: $stackTrace');
|
||||
} catch (e) {
|
||||
return Card(
|
||||
color: Colors.red[100],
|
||||
child: const ListTile(
|
||||
@@ -284,7 +224,6 @@ class _GroupContentState extends State<GroupContent> {
|
||||
}
|
||||
|
||||
Widget _buildEmptyState() {
|
||||
print('===== _buildEmptyState =====');
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
@@ -306,39 +245,49 @@ class _GroupContentState extends State<GroupContent> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildErrorState(String error, String userId) {
|
||||
print('===== _buildErrorState =====');
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(32),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.error, size: 64, color: Colors.red),
|
||||
const SizedBox(height: 16),
|
||||
const Text('Erreur', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500)),
|
||||
const SizedBox(height: 8),
|
||||
Text(error, textAlign: TextAlign.center, style: const TextStyle(fontSize: 12)),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton.icon(
|
||||
onPressed: () {
|
||||
print('>>> Bouton réessayer cliqué');
|
||||
Widget _buildErrorState(String error, String userId, bool retry) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (mounted) {
|
||||
if (retry) {
|
||||
if (userId == '') {
|
||||
showErrorDialog(
|
||||
context,
|
||||
title: 'Erreur utilisateur',
|
||||
message: 'Utilisateur non connecté. Veuillez vous reconnecter.',
|
||||
icon: Icons.error,
|
||||
iconColor: Colors.red,
|
||||
onRetry: () {
|
||||
Navigator.of(context).popUntil((route) => route.isFirst);
|
||||
},
|
||||
);
|
||||
} else {
|
||||
showErrorDialog(
|
||||
context,
|
||||
title: 'Erreur de chargement',
|
||||
message: error,
|
||||
icon: Icons.cloud_off,
|
||||
iconColor: Colors.orange,
|
||||
onRetry: () {
|
||||
context.read<GroupBloc>().add(LoadGroupsByUserId(userId));
|
||||
},
|
||||
icon: const Icon(Icons.refresh),
|
||||
label: const Text('Réessayer'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
}
|
||||
} else {
|
||||
showErrorDialog(
|
||||
context,
|
||||
title: 'Erreur',
|
||||
message: error,
|
||||
icon: Icons.error,
|
||||
iconColor: Colors.red,
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
}
|
||||
|
||||
void _openGroupChat(Group group) {
|
||||
print('===== _openGroupChat: ${group.name} =====');
|
||||
print('Group ID: ${group.id}');
|
||||
print('Group members: ${group.members.length}');
|
||||
|
||||
try {
|
||||
// Afficher juste un message, pas de navigation pour l'instant
|
||||
if (mounted) {
|
||||
@@ -359,7 +308,7 @@ class _GroupContentState extends State<GroupContent> {
|
||||
// );
|
||||
|
||||
} catch (e) {
|
||||
print('ERREUR openGroupChat: $e');
|
||||
_buildErrorState(e.toString(), '', false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user