Lesson 18 · 18 of 20
Exceptions · Dart
Handle errors in Dart with try, on, catch and finally, and raise your own with throw: a cash machine that refuses negative amounts and overdrafts.

When something goes wrong, Dart throws an exception and, if nobody handles it, the program stops. `try` marks the code that might fail and `on FormatException` handles that kind of error: int.parse('forty') fails, the warning is printed and the loop carries on as normal.
`throw` raises an exception of your own when something is not allowed. withdraw throws an `ArgumentError` if the amount is not positive and a `StateError` if there is not enough money; either way it never reaches return, so balance does not change.
A try can have several branches, which Dart tries in order. `on ArgumentError catch (e)` handles that type and keeps the error in e, whose message is the text given to throw. A `catch (e)` without on handles any other error: the StateError is printed in full as Bad state: not enough money.
`finally` always runs, error or not, which is why every operation ends with its checked line. It is the place for anything that must happen no matter what, such as closing a file.
In the end the balance is 70.0: only the first withdrawal worked, and the other two were refused without stopping the program.
Code · main.dart
// throw raises an error when something is not allowed.double withdraw(double balance, double amount) { if (amount <= 0) throw ArgumentError('the amount must be positive'); if (amount > balance) throw StateError('not enough money'); return balance - amount;}void main() { // int.parse fails with a FormatException on bad text. for (var text in ['42', 'forty']) { try { print('Read: ${int.parse(text)}'); } on FormatException { print('"$text" is not a number'); } } // on catches one type of error; catch (e) gives the error itself. double balance = 100; for (var amount in [30.0, -5.0, 500.0]) { try { balance = withdraw(balance, amount); print('Took out $amount, balance $balance'); } on ArgumentError catch (e) { print('Refused: ${e.message}'); } catch (e) { print('Error: $e'); } finally { // finally always runs, with or without an error. print(' operation of $amount checked'); } } print('Final balance: $balance');}Output · dart run main.dart
Read: 42 "forty" is not a number Took out 30.0, balance 70.0 operation of 30.0 checked Refused: the amount must be positive operation of -5.0 checked Error: Bad state: not enough money operation of 500.0 checked Final balance: 70.0
Key points
try { }wraps the code that might fail.on Typehandles one kind of error;catch (e)gives you the error.throw ArgumentError('...')raises your own error.finallyalways runs.- A handled error does not stop the program.
Exercise
Add a deposit function that throws an ArgumentError when the amount is over 1000, and try it inside a try with three amounts, one of them 2000.