fluent_result

pub package codecov likes style: lint Dart

fluent_result is a lightweight Dart library developed to solve a common problem. It returns an object indicating success or failure of an operation instead of throwing/using exceptions.

  • Store multiple errors in one Result object
  • Store powerful and elaborative Error object instead of only error messages in string format
  • Designing Errors in an object-oriented way

Usage

Creating a Result

Create a result which indicates success

Result result = Result.success();
Result successResult1 = Result.ok; // equivalent to a `Result.success()` but shorter

Create a result which indicates failure

Result errorResult1 = Result.withErrorMessage('a fail reason');
Result errorResult2 = Result.withError(ResultError('my error message'));
Result errorResult3 = Result.withException(MyException('exception description'));

Generic ResultOf<T>

Success result with value:

ResultOf<MyObject> result = ResultOf.success(MyObject());
MyObject value = result.value;

Fail result with error and without value:

ResultOf<MyObject> result = ResultOf.fail<MyObject>(ResultError('a fail reason'));
MyObject value = result.value; // is null because of the fail result

failIf() and okIf()

With the methods failIf() and okIf() you can also write in a more readable way:

final result1 = Result.failIf(() => firstName.isEmpty, "First Name is empty");
final result2 = Result.okIf(() => firstName.isNotEmpty, 'First name should not be empty');

Converting Result to another

To convert one success result to another success result has to be provided a valueConverter

final anotherResult =
    result.toResult(valueConverter: (customer) => User(customer.id));

To convert one fail result to another fail result

final anotherResult = failResult.toResult<Customer>();

Custom errors

To make your codebase more robust. Create your own error collection of the App by extending ResultError.
ResultError has key property which you can use for localization.


class InvalidPasswordError extends ResultError {
  const InvalidPasswordError(String message)
      : super(message, key: 'InvalidPasswordError');
}

class CustomerNotFound extends ResultError {
  const CustomerNotFound({
    required this.customerId,
  }) : super('Customer not found with ID $customerId');

  final int customerId;

  @override
  String toString() => message;
}

Collect errors

For example, easy to work with errors which comes from HTTP API.

final err1 = CustomerNotFound(customerId: 1);
final res = Result.fail(err1);

final err2 = InvalidPasswordError('The password 123456 is invalid');
res.add(err2);

res.contains<InvalidPasswordError>(); // true
res.get<InvalidPasswordError>().should.not.beNull();

Contributing

We accept the following contributions:

  • Improving documentation
  • Reporting issues
  • Fixing bugs

Maintainers

Libraries

fluent_result