catch handles thrown exceptions, while finally runs whether the protected work succeeds or fails.

Program

Play the program to see cleanup happen on both the normal path and the failure path.

try_catch_finally.dart
void main() {
  var shouldFail = ;
  var log = <String>[];
  try {
    log.add('open');
    if (shouldFail) throw StateError('boom');
    log.add('work');
  } catch (e) {
    log.add('catch');
  } finally {
    log.add('close');
  }
  print(log.join('>'));
}
void main() {
  var shouldFail = ;
  var log = <String>[];
  try {
    log.add('open');
    if (shouldFail) throw StateError('boom');
    log.add('work');
  } catch (e) {
    log.add('catch');
  } finally {
    log.add('close');
  }
  print(log.join('>'));
}
try The `try` block contains work that might throw.
catch `catch (e)` runs only for the thrown path.
finally `finally` always runs, making it suitable for cleanup.