catchError method
Executes a given asynchronous action within a try-catch block, handling loading states.
This method provides a convenient way to perform asynchronous operations while automatically managing loading states and error handling.
Parameters:
actions: A required function that contains the asynchronous operations to be performed.isLoading: An optional boolean that determines whether to show/hide loading indicators. Defaults to true.
Usage:
await blocCatch(
actions: () async {
// Perform some asynchronous operations
await fetchData();
await processData();
},
isLoading: true, // Optional, defaults to true
);
The method will:
- Show a loading indicator if
isLoadingis true. - Execute the provided
actions. - Hide the loading indicator after
actionscomplete or if an error occurs. - Log any errors that occur during execution.
Note: This method uses showLoading and hideLoading internally, which should be implemented in the concrete Bloc class or a mixin.
Implementation
Future<void> catchError({
required Future<void> Function() actions,
bool isLoading = true,
String keyLoading = LoadingKey.global,
Future<void> Function(Object error, StackTrace stackTrace)? onError,
Future<void> Function()? onFinally,
}) async {
try {
if (isLoading) {
showLoading(key: keyLoading);
}
await actions.call();
} on Exception catch (e, stackTrace) {
// Exceptions are expected, recoverable failures — route them to the
// caller's handler or log them and carry on.
if (onError != null) {
await onError(e, stackTrace);
} else {
developer.log(
'Error occurred: $e',
name: 'Error',
error: e,
stackTrace: stackTrace,
);
}
} on Error catch (e, stackTrace) {
// An Error is a bug, not a recoverable condition. Log it, then let it
// reach the zone handler and any crash reporter.
//
// A bare `catch` previously absorbed these too: a cubit closed during an
// await would throw StateError from emit, get swallowed, and leave stale
// UI with no crash report and no sign anything had gone wrong.
//
// The `finally` below still runs, so loading state is cleaned up before
// the error propagates.
developer.log(
'Unrecoverable error: $e',
name: 'Error',
error: e,
stackTrace: stackTrace,
);
rethrow;
} finally {
if (isLoading) {
hideLoading(key: keyLoading);
}
if (onFinally != null) {
await onFinally();
}
}
}