Home > database >  Dart: can't handle exceptions using the try catch block
Dart: can't handle exceptions using the try catch block

Time:01-06

I'm learning dart. I can't figure it out why the following dart code can't handle an exception. What wrong am I doing below?:

void main() {
  print(1);
  try {
    File file = File('random_path.txt');
    print(2);
    var contents = file.readAsString();
    print(3);
    contents.then((value) => print(value));
    print(4);
  } on FileSystemException catch (e) {
    print(5);
    print(e);
  } catch (e) {
    print(6);
    print(e);
  } finally {
    print(7);
  }

  print(8);
}

The file random_path.txt doesn't exist. I was expecting the on FileSystemException catch(e) to catch and print e. But that's not a case. Here is the output:

1
2
3
4
7
8
Unhandled exception:
FileSystemException: Cannot open file, path = 'random_path.txt' (OS Error: No such file or directory, errno = 2)
#0      _File.open.<anonymous closure> (dart:io/file_impl.dart:356:9)
<asynchronous suspension>

CodePudding user response:

You need to handle the error that is reported by the contents future, and forwarded to the future returned by then.

That means either adding an error handler yourself:

  contents.then(print).catchError((e, s) {
    print("Future error: $e\n$s");
  }); // Catches errors from `contents` or thrown by `print`.

// or

  contents.then(print, one rror: (e, s) {
    print("Future error: $e\n$s");
  }); // Won't catch error thrown by `print`.

Or using an async function to handle the future using await, which is the recommended approach:

void main() async { // <- marked as async so you can use `await`.
  print(1);
  try {
    File file = File('random_path.txt');
    print(2);
    Future<String> contents = file.readAsString();
    print(3);
    var value = await contents; // <- await gets value, or rethrows error
    print(value);
    print(4);
  } on FileSystemException catch (e) {
    print(5);
    print(e);
  } catch (e) {
    print(6);
    print(e);
  } finally {
    print(7);
  }
  print(8);
}

In general, always use async functions and await to deal with futures. Using the .then API is mainly for low-level code which integrates different asynchronous computations, and has to wait for more than one thing at a time. It's what's being used internally to build a good Future based API that you can just await on. And you should just await when you can.

  • Related