Skip to content

Commit be6df1e

Browse files
committed
rfac: error handling in profile bloc
1 parent a3c4ad2 commit be6df1e

4 files changed

Lines changed: 40 additions & 13 deletions

File tree

lib/domain/repositories/user_repository.dart

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:convert';
22
import 'dart:io';
33

44
import '../../data/config/config.dart';
5+
import '../../data/constants/strings.dart';
56
import '../../data/services/local/storage_service.dart';
67
import '../../data/services/remote/api_service.dart';
78
import '../../utils/auth_token.dart' as auth_token_utils;
@@ -196,7 +197,8 @@ class UserRepository {
196197
response['data'].map((e) => Following.fromJson(e)),
197198
);
198199
}
199-
return null;
200+
201+
throw Exception(AppStrings.genericError);
200202
}
201203

202204
static Future<bool> verifyHandle(String site, String handle) async {
@@ -225,6 +227,7 @@ class UserRepository {
225227
_users.add(User.fromJson(user));
226228
}
227229
}
230+
228231
return _users;
229232
}
230233

@@ -261,7 +264,8 @@ class UserRepository {
261264
if (response['status_code'] == 200) {
262265
return SubmissionStatus.fromJson(response['data']);
263266
}
264-
return null;
267+
268+
throw Exception(AppStrings.genericError);
265269
}
266270

267271
static Future<List<ActivityDetails>?> getActivityDetails(String id) async {
@@ -279,7 +283,8 @@ class UserRepository {
279283
response['data'].map((e) => ActivityDetails.fromJson(e)),
280284
);
281285
}
282-
return null;
286+
287+
throw Exception(AppStrings.genericError);
283288
}
284289

285290
static Future<int> updatePassword(

lib/presentation/profile/bloc/profile_bloc.dart

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import '../../../data/constants/strings.dart';
99
import '../../../data/services/local/storage_service.dart';
1010
import '../../../domain/models/activity_details.dart';
1111
import '../../../domain/models/following.dart';
12+
import '../../../domain/models/status.dart';
1213
import '../../../domain/models/submission_status.dart';
1314
import '../../../domain/models/user.dart';
1415
import '../../../domain/repositories/user_repository.dart';
@@ -26,7 +27,9 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
2627
}
2728

2829
void _onFetchDetails(FetchDetails event, Emitter<ProfileState> emit) async {
29-
if (!state.isLoading) emit(state.copyWith(isLoading: true));
30+
if (state.status is! Loading) {
31+
emit(state.copyWith(status: const Status.loading()));
32+
}
3033

3134
// Fetch user details
3235
if (event.userId.isEmpty) {
@@ -35,12 +38,19 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
3538
_user = await UserRepository.fetchUserDetails(uid: event.userId);
3639
}
3740

38-
_followingList = await UserRepository.getFollowingList();
41+
SubmissionStatus? _subStats;
42+
List<ActivityDetails>? _activityDetails;
43+
// TODO(aman-singh7): Throw specific Error
44+
try {
45+
_followingList = await UserRepository.getFollowingList();
3946

40-
final _subStats = await UserRepository.getSubmissionStatusData(_user!.id!);
47+
_subStats = await UserRepository.getSubmissionStatusData(_user!.id!);
4148

42-
final _activityDetails =
43-
await UserRepository.getActivityDetails(_user!.id!);
49+
_activityDetails = await UserRepository.getActivityDetails(_user!.id!);
50+
} on Exception catch (_) {
51+
emit(state.copyWith(status: const Status.error(AppStrings.genericError)));
52+
return;
53+
}
4454

4555
for (final activity in _activityDetails ?? <ActivityDetails>[]) {
4656
if (activity.createdAt == null) continue;
@@ -58,7 +68,7 @@ class ProfileBloc extends Bloc<ProfileEvent, ProfileState> {
5868
_isFollowing ??= false;
5969

6070
emit(state.copyWith(
61-
isLoading: false,
71+
status: const Status(),
6272
user: _user,
6373
following: _followingList,
6474
submissionStatus: _subStats,

lib/presentation/profile/bloc/profile_state.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ part of 'profile_bloc.dart';
33
@freezed
44
class ProfileState with _$ProfileState {
55
const factory ProfileState({
6-
@Default(true) bool isLoading,
6+
@Default(Status.loading()) Status status,
77
@Default(true) bool personalProfile,
88
@Default(false) bool isFollowing,
99
@Default(false) bool showFollowing,

lib/presentation/profile/profile_screen.dart

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_bloc/flutter_bloc.dart';
33
import 'package:flutter_screenutil/flutter_screenutil.dart';
44

5+
import '../../data/constants/strings.dart';
56
import '../../data/constants/styles.dart';
7+
import '../../domain/models/status.dart';
8+
import '../../utils/snackbar.dart';
69
import 'bloc/profile_bloc.dart';
710
import 'widgets/acceptance_graph.dart';
811
import 'widgets/accuracy_display.dart';
@@ -19,13 +22,22 @@ class ProfileScreen extends StatelessWidget {
1922
Widget build(BuildContext context) {
2023
return BlocProvider(
2124
create: (context) => ProfileBloc()..add(const FetchDetails()),
22-
child: BlocBuilder<ProfileBloc, ProfileState>(
25+
child: BlocConsumer<ProfileBloc, ProfileState>(
26+
listenWhen: (previous, current) =>
27+
previous.status.hashCode != current.status.hashCode,
28+
listener: (context, state) {
29+
if (state.status is Error) {
30+
showSnackBar(message: AppStrings.genericError);
31+
}
32+
},
2333
// When Loading state changes
2434
buildWhen: (previous, current) =>
25-
previous.isLoading ^ current.isLoading ||
35+
previous.status.hashCode != current.status.hashCode ||
2636
previous.showFollowing ^ current.showFollowing,
2737
builder: (context, state) {
28-
if (state.isLoading) return const ProfileLoadingState();
38+
if (state.status is Loading || state.status is Error) {
39+
return const ProfileLoadingState();
40+
}
2941

3042
if (state.showFollowing) return const FollowingView();
3143

0 commit comments

Comments
 (0)