Result

Traditionally, we usually handle potentially thrown exceptions with try and catch. This may lead to multiple-wrapped try and catch statements and will cause difficulties in reading code and implementation.

Future<String> fetchString() async {
    try {
        return rootBundle.loadString(path);
    } catch (e) {
        throw Exception();
    }
}

Future<int> convertStringToInt() async {
    try {
        final text = await fetchString();
        return int.parse(text);
    } catch (e) {
        throw Exception();
    }
}

void main() async {
    try {
        final number = await convertStringToInt();
    } catch (e) {
        rethrow;
    }
}

With this style of implementation, developers may find it difficult to be aware of whether functions potentially throw exceptions without checking the implementation. Moreover, wrapping many layers of try and catch causes inflexibility in handling each type of exception.

Therefore, we provide a Result as a solution for this.

Future<Result<String, Object>> fetchString() async {
    try {
      final text = await rootBundle.loadString('sdf');

      return Result.success(text);
    } catch (e) {
      return Result.failure(e);
    }
}

Future<Result<int, Object>> convertStringToInt() async {
    final result = await fetchString();

    if (result is Success<String>) {
      try {
        final number = int.parse(result.data);
        return Result.success(number);
      } catch (e) {
        return Result.failure(e);
      }
    } else {
      result as Failure<Object>;

      return Result.failure(result.exp);
    }
}

void main() async {
    final result = await convertStringToInt();

    if(result is Success<int>){
        print(result.data);
    } else {
        result as Failure<Object>;
        print(result.exp);
    }
}

Result<T, E>

  • T: is the type of output in case of being successful.

  • E: is the type of object that will be thrown in case of being failed.

When being successful, there are 2 ways to define:

  • Result.success(data)

  • Success(data)

When being failed, there are 2 ways to define:

  • Result.failure(exception)

  • Failure(exception)