resultex 2.3.0 copy "resultex: ^2.3.0" to clipboard
resultex: ^2.3.0 copied to clipboard

A robust core architecture ecosystem for Flutter and Dart, providing unified dependency injection and error management utilities.

Resultex #

A robust, type-safe error handling ecosystem for Dart and Flutter that implements the Result pattern for clean, predictable error handling without exceptions.

pub package License: MIT

๐Ÿ“ฆ Overview #

resultex brings a functional programming approach to error handling by wrapping your operational outcomes in a type-safe container. Instead of throwing heavy exceptions and messing up your call stack, every function returns a Result that is either a SuccessResult wrapping your value or a FailureResult containing structured error details.

Why Resultex? #

  • ๐Ÿ›ก๏ธ Zero Try-Catch Boilerplate - Handle operational errors exactly where they matter.
  • ๐Ÿ”’ Type-Safe Destructuring - The Dart compiler ensures you handle both success and failure states.
  • ๐Ÿงฉ Pattern Matching - Fully optimized for Dart 3+ exhaustive switch expressions.
  • ๐Ÿš‚ Composable Pipelines - Chain complex operations effortlessly with map and flatMap.
  • ๐Ÿงช Highly Testable - Predictable control flow, making Unit Testing a breeze without unexpected runtime crashes.
  • ๐Ÿ’Ž Clean Architecture Approved - Follows SOLID principles, separating business logic outcomes from presentation layers.

๐Ÿš€ Installation #

Prerequisites #

  • Dart SDK: >=3.0.0 <4.0.0
  • Flutter SDK: >=3.10.0

Add resultex to your pubspec.yaml:

dependencies:
  resultex: ^2.2.0

๐ŸŽฏ Core Concepts #

  1. Successful Result

final result = Result.success(User(id: 1, name: "Hassan"));
// Contains a SuccessResult wrapping a Success<User> container
  1. Failure Result

final result = Result.failure(Failure(message: "Network request timeout"));
// Contains a FailureResult with messages, codes, and optional stackTraces
  1. Exhaustive Pattern Matching (Dart 3+)
switch (result) {
case SuccessResult<User>(success: Success(:final value)):
print('Welcome back, ${value.name}!');
case FailureResult<User>(failure: final fail):
print('Error occurred: ${fail.message}');
}

๐ŸŽจ Reactive UI Layer (New in v2.3.0) #

๐Ÿšฆ State Management via ResultNotifier
A lightweight, lifecycle-aware alternative to heavy state management boilerplate. Track any asynchronous operation safely inside your controllers or state classes.


final userNotifier = ResultNotifier<User>();

// Automatically handles loading state, catches unexpected errors, and updates the UI
userNotifier.track
(
repository
.
fetchUserProfile
(
)
);

๐Ÿงฑ Declarative Layouts via ResultBuilder
Eliminate bloated conditions inside your widget tree. Separate your UI cleanly into three predictable layout paths.

@override
Widget build(BuildContext context) {
  return ResultBuilder<User>(
    notifier: _userNotifier,
    onLoading: (context) => const CircularProgressIndicator(),
    onFailure: (context, failure) => Text('Error: ${failure.message}'),
    onSuccess: (context, user) => Text('Hello, ${user.name}'),
  );
}

๐Ÿš‚ Advanced Functional Pipelines #

๐Ÿ”„ Asynchronous Chaining (asyncMap & asyncFlatMap) Chain multiple asynchronous dependencies sequentially without running into await callback hell.

// Streamline complex database/network pipelines elegantly
Future<Result<Orders>> ordersResult = repository.getUser(1) // Future<Result<User>>
    .asyncMap((user) => user.id) // Future<Result<int>>
    .asyncFlatMap((id) => orderRepository.getOrders(id)); // Future<Result<Orders>>

๐ŸŽญ Adapting Errors downstream (mapFailure)
Transform internal exceptions into localized or presentation-friendly error messages before hitting the UI.


final uiResult = apiResult.mapFailure(
      (fail) => Failure(message: 'Localized Error: ${fail.message}'),
);

๐Ÿ”„ Resilient Operation Retries (withRetry)
Attach configurable recovery retries to any transient network dispatch with support for exponential backoff.


final networkResult = await
Result.guardAsync
(
() => (() => http.get(uri)).withRetry(
const RetryOptions(maxAttempts: 3, delay: Duration(seconds: 2), backoffFactor: 2.0),
),
);

๐ŸŽจ Advanced Features & Extensions #

  1. UI Layer Clean Mapping (.when()) The package provides a tailored Flutter extension to directly map your Result states into widgets inside the build method without bloated conditions.
import 'package:resultex/core/utils/result_flutterx_extension.dart';

@override
Widget build(BuildContext context) {
  return userResult.when(
    onSuccess: (user) => Text('Hello, ${user.name}'),
    onFailure: (failure) => Text('Error: ${failure.message}'),
  );
}
  1. Concurrent Parallel Execution (ResultUtils.combineAll) When executing multiple operations simultaneously, ResultUtils.combineAll fires them in parallel. If any operation fails, it aggregates all intercepted errors into a unified MultiFailure contract instead of short-circuiting on the first error.
import 'package:resultex/core/utils/result_utils.dart';

final Result<List<dynamic>> dashboardResult = await
ResultUtils.combineAll
([repository.fetchUserProfile(), // Future<Result<User>>
repository.fetchNotifications(), // Future<Result<List<Notif>>>
repository.fetchCryptoWallet(), // Future<Result<Wallet>>
]);

dashboardResult.when(
onSuccess: (data) {
final user = data[0] as User;
final wallet = data[2] as CryptoWallet;
// Render your screen using safely casted data
},
onFailure: (failure) {
if (failure is MultiFailure) {
print('${failure.failures.length} operations failed concurrently.');
}
},
);
  1. Operational Recovery Path (.recover()) Intercept an operational Failure and route it through an alternative backup execution pipeline smoothly.

Result<User> userResult = await
authRepository.fetchRemoteUser
();

Result<User> finalizedResult = userResult.recover((failure) {
  print('Remote fetch failed: ${failure.message}. Falling back to local cache...');
  return Result.success(localDatabase.getCachedUser());
});

๐Ÿ“– Fluid Usage Guide
Safe Execution Closures (guard / guardAsync) Automatically intercept synchronous or asynchronous unexpected exceptions and encapsulate them into safe Result variants.

// Synchronous parsing guard
final result = Result.guard(() => jsonDecode(rawJsonString));
// Asynchronous API call guard
final networkResult = await
Result.guardAsync
(
() => http.get(Uri.parse(url
)
)
);

Functional Chaining (map & flatMap)
Transform successful values or sequentially chain multiple business operations without nesting blocks.

// Map values on success
final nameResult = result.map((user) => user.name); // Result<String>

// Chain dependencies flatly
final ordersResult = await
repository.getUser
(1)
.then((res) => res.flatMap((user) => orderRepository.getOrders(user.id)
)
);

๐Ÿ”ง Advanced ResultExecutor Architecture
Wrap execution scopes into monitored contexts complete with automated structured logging and error tracking capabilities.


final executor = ResultExecutor(logger: AppLogger());
final result = await
executor.executeAsync
(
() async {
`final data = await api.fetchData();
`return processData(data);
},
context
:
fetchAndProcessDashboardData
);

๐Ÿ—๏ธ Best Practices #

โœ… DO

  • Use ResultUtils.combineAll for maximizing parallel performance across independent network dispatches.
  • Use the .when() extension inside Flutter layout building pipelines for pristine scannability.
  • Provide meaningful context tags within ResultExecutor blocks to maintain bulletproof debug logs.

โŒ DON'T

  • Don't force-extract values without evaluating state via pattern matching or explicit folds.
  • Don't catch generic raw exceptions manually inside execution blocks managed by guard hooks.

๐Ÿ“„ License #

This project is licensed under the MIT License - see the LICENSE file for details. Open Source development is respected; feel free to modify, distribute, and implement this package in both public repositories and enterprise closed-source commercial systems.

Made with โค๏ธ for clean, maintainable Dart & Flutter code architectures. #

2
likes
0
points
657
downloads

Publisher

verified publishercodearastudio.ir

Weekly Downloads

A robust core architecture ecosystem for Flutter and Dart, providing unified dependency injection and error management utilities.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

equatable, flutter, get_it, resultex_logger

More

Packages that depend on resultex