'The return type 'void' isn't assignable to 'FutureOr<T>', as required by 'Future.catchError'

I have some code like this:

File("foo.txt").readAsString().catchError((e)=>print(e));

The compiler is complaining info: The return type 'void' isn't assignable to 'FutureOr<T>', as required by 'Future.catchError'.

I can't seem to give it what it wants and can't find a single clear usage example in any of the docs (just a long issue in git about how many ways there are to mis-use this). If I take the docs at face value, I should be able to return a bool, or a future, neither make the analyzer happy.

How do I provide this FutureOr?



Solution 1:[1]

The documentation for Future.catchError could be a lot clearer, but the relevant part is:

onError is called with the error and possibly stack trace, and the returned future is completed with the result of this call in exactly the same way as for then's onError.

Cross-referencing to the documentation for Future.then, the relevant portion is:

The onError callback must return a value or future that can be used to complete the returned future, so it must be something assignable to FutureOr<R>.

Since File.readAsString returns a Future<String>, your catchError callback also must return a Future<String>. Examples of doing that:

File("foo.txt").readAsString().catchError((e) {
  print(e);
  return Future.value('');
});

File("foo.txt").readAsString().catchError((e) async {
  print(e);
  return '';
});

Logically, this makes sense; because given:

String value = await File("foo.txt").readAsString().catchError(...);

then if readAsString succeeds, value should be assigned a String. If it fails, since you catch the exception without rethrowing it, value still needs to be assigned a String.

Put another way, your code is equivalent to:

Future<String> readFoo() async {
  try {
    return await File("foo.txt").readAsString();
  } catch (e) {
    print(e);
  }
  // Oops, missing return value.
}

In general, I strongly recommend using async/await with try-catch instead of using .catchError, which would avoid this confusion.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1