safe_bloc

Last updated:

0 purchases

safe_bloc Image
safe_bloc Images
Add to Cart

Description:

safe bloc

Developed with 💚 by netglade






An extension to bloc state management library that manages unexpected exceptions in a code and displays them as customizable user-friendly error messages.
Overview #
A library that provides a unified solution to code exception handling in blocs and cubits. In addition, it presents the errors to the user using a dedicated widget UnexpectErrorHandler. This widget can be customized so that all the error dialogs and screens match your app design. Moreover, the exception processing is customizable, they can be either displayed, logged, or ignored. safe_bloc also offers the advantage of an optional onUnexpectedError callback, that is called each time an exception occurs. This can be suitable especially for exception logging.
This library also distinguishes between two types of error: error state and error actions:


Error states: These occur only during the initial screen loading. If the screen loading fails, there's no data to display to the user, and the UnexpectErrorHandler presents an error screen represented by the errorScreen parameter.


Error actions: These typically happen when a user triggers an action (e.g., pressing a button) on an already loaded screen. In this scenario, we don't want to disrupt the user's experience by displaying an error screen and erasing the loaded data. Instead, the safe_bloc library simply shows an error dialog, informing the user that the action is currently unavailable. This ensures that the screen's existing data remains accessible to the user.


Usage #
1. Create UnexpectedError state #
First, create an error state that will be emitted in case an exception occurs. This state must implement UnexpectedErrorBase.
sealed class MyAppState {}

final class MyAppErrorState extends MyAppState implements UnexpectedErrorBase {
@override
final UnexpectedError error;

MyAppErrorState(this.error);
}
copied to clipboard
2. Use SafeBloc or SafeCubit class #
Bloc
In case you are using Bloc, extend your bloc with a SafeBloc class and override its errorState getter with the error state created in the previous step:
class MyAppBloc extends SafeBloc<MyAppEvent, MyAppState> {
// body

@override
MyAppState Function(UnexpectedError error) get errorState => MyAppErrorState.new;
}
copied to clipboard
Now, whenever you register a new event handler, use onSafe<EVENT>
event handler instead of standard on<EVENT>:
onSafe<MyBlocEvent>(event, emit, {required trackingId}) async {
// do something
}
copied to clipboard
Cubit
Similarly, if you are using Cubit, extend your cubit with as SafeCubit class and override the errorState getter with the error state you have created in the first step. Then, wrap all the public cubit methods in a safeCall method as follows:
class MyAppCubit extends SafeCubit<MyAppState> {
MyAppCubit(super.initialState);

FutureOr<void> someMethod() => safeCall((trackingId) {
// do something
});

@override
MyAppState Function(UnexpectedError error) get errorState => MyAppErrorState.new;
}
copied to clipboard
Alternatively, if your cubit method is synchronous, you can wrap it in safeCallSync method.
Each time an exception occurs, it is caught by the parent class and MyAppErrorState is emitted. This state contains an UnexpectedError object with additional information about the exception including the exception itself.
Both onSafe and safeCall provide a unique trackingId that can be used to track the user actions. Both methods also provide additional parameters:

devErrorMessage(optional) - string message that is passed to the UnexpectedError object, can be handy for logging
isAction- bool that indicates if the method is an error action or error state. When set to true, UnexpectedErrorHandler shows an error dialog or calls onErrorAction callback if specified. When set to false (default), UnexpectedErrorHandler shows an error screen specified by errorScreen parameter.
ignoreError - bool that indicates whether the exception should be ignored. If set to true, the exception is caught, but MyAppErrorState is not emitted.
onIgnoreError(optional) - a callback that is invoked if the exception occurs and ignoreError parameter is set to true
errorMapper(optional) - a function that maps individual exceptions to bloc/cubit states. If null, all exceptions are mapped to MyAppErrorState.

Additionally, SafeBloc and SafeCubit offer the option to override the onUnexpectedError method. This method is invoked whenever an exception is thrown so that it can be useful for exception logging.
3. Present the error in the UI #
Use the UnexpectErrorHandler in your widget tree in order to display the errors:
UnexpectedErrorHandler<MyAppBloc, MyAppState>(
errorScreen: (context, error) => Text(error.toString()),
onErrorAction: (context, error) {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(title: Text(error.toString()));
},
);
},
child: MyWidget(),
)
copied to clipboard
UnexpectErrorHandler provides a parameter errorScreen to display the errors during the initial screen loading and parameter onErrorAction for the error actions. onErrorAction callback is invoked if the isAction parameter of the onSafe/safeCall method is set to true.
Using presentation events in you app #
This library makes use of the bloc_presentation library to handle the user error action events. bloc_presentation adds another stream to the bloc/cubit in order to present one-time events (e.g. dialogs or snackbars) to the user. safe_bloc library uses a BaseEffect as a presentation event
and its inherited UnexpectedErrorEffect class for exception handling. However, if you have specific presentation events you would like to use in your bloc or cubit, you can create your own implementation of presentation events and use them in combination with SafeBlocWithPresentation or SafeCubitWithPresentation like this:
class MyAppCubit extends SafeCubitWithPresentation<MyAppState, MyAppPresentationEvent> {
MyAppCubit(super.initialState);

FutureOr<void> someMethod() => safeCall((trackingId) {
// do something
});

@override
MyAppState Function(UnexpectedError error) get errorState => MyAppErrorState.new;

@override
MyAppPresentationEvent Function(UnexpectedError error) get errorEffect => MyAppErrorPresentationEvent.new;
}
copied to clipboard

License:

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Files In This Product:

Customer Reviews

There are no reviews.