flutterdarterror-handlingunhandled-exception

unhandled exception in then().catchError in Flutter


    onPressed: () {
      getName().then((value)
        {
          print(value);
          print('YNWA');
          throw('ERORRRRRR!');
        }).catchError((error){
          print('error is : ${error.toString()}');
      });
    },
  

and here is a method

 Future<String> getName() async {
return 'Basel Elazaly';

} }

why there is unhandled exception?


Solution

  • You haven't specified what unhandled exception you're getting. When I try it with:

    Future<String> getName() async {
      return 'Basel Elazaly';
    }
    
    void main() {
      getName().then((value) {
        print(value);
        print('YNWA');
        throw ('ERORRRRRR!');
      }).catchError((error) {
        print('error is : ${error.toString()}');
      });
    }
    

    the thrown 'ERORRRRRR!' string is caught. However, the analyzer warns you that your catchError block is incorrect because it doesn't return the correct type, and that incorrectness results in a separate runtime error.

    "What return type?" you might be wondering. Your Future.then callback's body is:

        print(value);
        print('YNWA');
        throw ('ERORRRRRR!');
    

    which unconditionally does throw ('ERORRRRRR!'). Therefore the return type of the Future is inferred to be a Future<Never> because that callback is statically determined to never returns normally. Therefore the return type of your Future.catchError callback also must be of type Future<Never>.

    If your callback body instead were:

        print(value);
        print('YNWA');
        
        bool alwaysTrue() => true;
        if (alwaysTrue()) {
          throw ('ERORRRRRR!');
        }
    

    then that would be sufficient to prevent static analysis from determining that the throw is always executed, the return type would be inferred as Future<void> instead, the return type of the Future.catchError callback would match, and you wouldn't end up with an unhandled exception.

    The moral of the story (and of all stories that involve Future.catchError) is that you shouldn't be using Future.catchError at all. If you want to catch an error from a Future, await that Future with a try block and use catch to handle whatever's thrown.