feat: Centralized Error Handling & Crash Fixes

This commit is contained in:
2026-02-11 18:52:23 +05:30
parent ea06510474
commit c1112ac01c
51 changed files with 2104 additions and 960 deletions

View File

@@ -42,8 +42,11 @@ class AttirePage extends StatelessWidget {
body: BlocConsumer<AttireCubit, AttireState>(
listener: (BuildContext context, AttireState state) {
if (state.status == AttireStatus.failure) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(state.errorMessage ?? 'Error')),
UiSnackbar.show(
context,
message: translateErrorKey(state.errorMessage ?? 'Error'),
type: UiSnackbarType.error,
margin: const EdgeInsets.only(bottom: 150, left: 16, right: 16),
);
}
if (state.status == AttireStatus.saved) {

View File

@@ -42,15 +42,13 @@ class EmergencyContactScreen extends StatelessWidget {
listener: (context, state) {
if (state.status == EmergencyContactStatus.failure) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
state.errorMessage != null
? translateErrorKey(state.errorMessage!)
: 'An error occurred',
),
behavior: SnackBarBehavior.floating,
),
UiSnackbar.show(
context,
message: state.errorMessage != null
? translateErrorKey(state.errorMessage!)
: 'An error occurred',
type: UiSnackbarType.error,
margin: const EdgeInsets.only(bottom: 150, left: 16, right: 16),
);
}
},

View File

@@ -16,14 +16,11 @@ class EmergencyContactSaveButton extends StatelessWidget {
listenWhen: (previous, current) => previous.status != current.status,
listener: (context, state) {
if (state.status == EmergencyContactStatus.saved) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Emergency contacts saved successfully',
style: UiTypography.body2r.textPrimary,
),
backgroundColor: UiColors.iconSuccess,
),
UiSnackbar.show(
context,
message: 'Emergency contacts saved successfully',
type: UiSnackbarType.success,
margin: const EdgeInsets.only(bottom: 150, left: 16, right: 16),
);
}
},

View File

@@ -58,20 +58,21 @@ class ExperiencePage extends StatelessWidget {
child: BlocConsumer<ExperienceBloc, ExperienceState>(
listener: (context, state) {
if (state.status == ExperienceStatus.success) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Experience saved successfully')),
UiSnackbar.show(
context,
message: 'Experience saved successfully',
type: UiSnackbarType.success,
margin: const EdgeInsets.only(bottom: 120, left: 16, right: 16),
);
Modular.to.pop();
} else if (state.status == ExperienceStatus.failure) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
state.errorMessage != null
? translateErrorKey(state.errorMessage!)
: 'An error occurred',
),
behavior: SnackBarBehavior.floating,
),
UiSnackbar.show(
context,
message: state.errorMessage != null
? translateErrorKey(state.errorMessage!)
: 'An error occurred',
type: UiSnackbarType.error,
margin: const EdgeInsets.only(bottom: 120, left: 16, right: 16),
);
}
},

View File

@@ -14,7 +14,7 @@ import 'personal_info_state.dart';
/// during onboarding or profile editing. It delegates business logic to
/// use cases following Clean Architecture principles.
class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
with BlocErrorHandler<PersonalInfoState>
with BlocErrorHandler<PersonalInfoState>, SafeBloc<PersonalInfoEvent, PersonalInfoState>
implements Disposable {
/// Creates a [PersonalInfoBloc].
///
@@ -54,8 +54,8 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
'phone': staff.phone,
'preferredLocations':
staff.address != null
? <String?>[staff.address]
: <dynamic>[], // TODO: Map correctly when Staff entity supports list
? <String>[staff.address!]
: <String>[], // TODO: Map correctly when Staff entity supports list
'avatar': staff.avatar,
};
@@ -109,8 +109,8 @@ class PersonalInfoBloc extends Bloc<PersonalInfoEvent, PersonalInfoState>
'phone': updatedStaff.phone,
'preferredLocations':
updatedStaff.address != null
? <String?>[updatedStaff.address]
: <dynamic>[],
? <String>[updatedStaff.address!]
: <String>[],
'avatar': updatedStaff.avatar,
};

View File

@@ -28,24 +28,19 @@ class PersonalInfoPage extends StatelessWidget {
child: BlocListener<PersonalInfoBloc, PersonalInfoState>(
listener: (BuildContext context, PersonalInfoState state) {
if (state.status == PersonalInfoStatus.saved) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(i18n.save_success),
duration: const Duration(seconds: 2),
),
UiSnackbar.show(
context,
message: i18n.save_success,
type: UiSnackbarType.success,
);
Modular.to.pop();
} else if (state.status == PersonalInfoStatus.error) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
state.errorMessage != null
? translateErrorKey(state.errorMessage!)
: 'An error occurred',
),
behavior: SnackBarBehavior.floating,
duration: const Duration(seconds: 3),
),
UiSnackbar.show(
context,
message: state.errorMessage != null
? translateErrorKey(state.errorMessage!)
: 'An error occurred',
type: UiSnackbarType.error,
);
}
},