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

@@ -62,7 +62,10 @@ class ViewOrdersCubit extends Cubit<ViewOrdersState>
);
_updateDerivedState();
},
onError: (String _) => state.copyWith(status: ViewOrdersStatus.failure),
onError: (String message) => state.copyWith(
status: ViewOrdersStatus.failure,
errorMessage: message,
),
);
}

View File

@@ -15,9 +15,11 @@ class ViewOrdersState extends Equatable {
this.activeCount = 0,
this.completedCount = 0,
this.upNextCount = 0,
this.errorMessage,
});
final ViewOrdersStatus status;
final String? errorMessage;
final List<OrderItem> orders;
final List<OrderItem> filteredOrders;
final List<DateTime> calendarDays;
@@ -39,9 +41,11 @@ class ViewOrdersState extends Equatable {
int? activeCount,
int? completedCount,
int? upNextCount,
String? errorMessage,
}) {
return ViewOrdersState(
status: status ?? this.status,
errorMessage: errorMessage ?? this.errorMessage,
orders: orders ?? this.orders,
filteredOrders: filteredOrders ?? this.filteredOrders,
calendarDays: calendarDays ?? this.calendarDays,
@@ -66,5 +70,6 @@ class ViewOrdersState extends Equatable {
activeCount,
completedCount,
upNextCount,
errorMessage,
];
}

View File

@@ -68,7 +68,17 @@ class _ViewOrdersViewState extends State<ViewOrdersView> {
@override
Widget build(BuildContext context) {
return BlocBuilder<ViewOrdersCubit, ViewOrdersState>(
return BlocConsumer<ViewOrdersCubit, ViewOrdersState>(
listener: (BuildContext context, ViewOrdersState state) {
if (state.status == ViewOrdersStatus.failure &&
state.errorMessage != null) {
UiSnackbar.show(
context,
message: translateErrorKey(state.errorMessage!),
type: UiSnackbarType.error,
);
}
},
builder: (BuildContext context, ViewOrdersState state) {
final List<DateTime> calendarDays = state.calendarDays;
final List<OrderItem> filteredOrders = state.filteredOrders;
@@ -101,64 +111,66 @@ class _ViewOrdersViewState extends State<ViewOrdersView> {
// Content List
Expanded(
child: filteredOrders.isEmpty
? _buildEmptyState(context: context, state: state)
: ListView(
padding: const EdgeInsets.fromLTRB(
UiConstants.space5,
UiConstants.space4,
UiConstants.space5,
100,
),
children: <Widget>[
if (filteredOrders.isNotEmpty)
Padding(
padding: const EdgeInsets.only(
bottom: UiConstants.space3,
),
child: Row(
children: <Widget>[
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: dotColor,
shape: BoxShape.circle,
),
),
const SizedBox(
width: UiConstants.space2,
),
Text(
sectionTitle.toUpperCase(),
style: UiTypography.titleUppercase2m
.copyWith(
color: UiColors.textPrimary,
),
),
const SizedBox(
width: UiConstants.space1,
),
Text(
'(${filteredOrders.length})',
style: UiTypography.footnote1r
.copyWith(
color: UiColors.textSecondary,
),
),
],
),
child: state.status == ViewOrdersStatus.failure
? _buildErrorState(context: context, state: state)
: filteredOrders.isEmpty
? _buildEmptyState(context: context, state: state)
: ListView(
padding: const EdgeInsets.fromLTRB(
UiConstants.space5,
UiConstants.space4,
UiConstants.space5,
100,
),
...filteredOrders.map(
(OrderItem order) => Padding(
padding: const EdgeInsets.only(
bottom: UiConstants.space3,
children: <Widget>[
if (filteredOrders.isNotEmpty)
Padding(
padding: const EdgeInsets.only(
bottom: UiConstants.space3,
),
child: Row(
children: <Widget>[
Container(
width: 8,
height: 8,
decoration: BoxDecoration(
color: dotColor,
shape: BoxShape.circle,
),
),
const SizedBox(
width: UiConstants.space2,
),
Text(
sectionTitle.toUpperCase(),
style: UiTypography.titleUppercase2m
.copyWith(
color: UiColors.textPrimary,
),
),
const SizedBox(
width: UiConstants.space1,
),
Text(
'(${filteredOrders.length})',
style: UiTypography.footnote1r
.copyWith(
color: UiColors.textSecondary,
),
),
],
),
),
...filteredOrders.map(
(OrderItem order) => Padding(
padding: const EdgeInsets.only(
bottom: UiConstants.space3,
),
child: ViewOrderCard(order: order),
),
),
child: ViewOrderCard(order: order),
),
],
),
],
),
),
],
),
@@ -208,4 +220,36 @@ class _ViewOrdersViewState extends State<ViewOrdersView> {
if (checkDate == tomorrow) return 'Tomorrow';
return DateFormat('EEE, MMM d').format(date);
}
Widget _buildErrorState({
required BuildContext context,
required ViewOrdersState state,
}) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Icon(
UiIcons.error,
size: 48,
color: UiColors.error,
),
const SizedBox(height: UiConstants.space4),
Text(
state.errorMessage != null
? translateErrorKey(state.errorMessage!)
: 'An error occurred',
style: UiTypography.body1m.textError,
textAlign: TextAlign.center,
),
const SizedBox(height: UiConstants.space4),
UiButton.secondary(
text: 'Retry',
onPressed: () => BlocProvider.of<ViewOrdersCubit>(context)
.jumpToDate(state.selectedDate ?? DateTime.now()),
),
],
),
);
}
}