← → or space · progress saves for Continue on the roadmap
Goal
Catch recoverable failures, always clean up in finally, and throw meaningful errors.
Step 1 - Throw
void pay(double amount) {
if (amount.isNaN || amount.isInfinite) {
throw ArgumentError('amount must be finite');
}
}
void main() {
try {
pay(double.nan);
} catch (e) {
print(e);
}
}Step 2 - try / catch / finally
int parseLen(String raw) {
try {
final n = int.parse(raw);
return n;
} on FormatException {
return 0;
} finally {
print('parse attempt done');
}
}
void main() {
print(parseLen('12'));
print(parseLen('nope'));
}on Typenarrows what you catch. A barecatch (e, st)catches everything (use sparingly).
Step 3 - Stack trace preserved (optional)
catch (e, st)gives you the stackstif you log or wrap withError.throwWithStackTrace.- In app code, often log
eandstat the outer boundary, not inside every helper.
Good habit
- Catch at boundaries (CLI entry, HTTP handler), not in every tiny helper.
Practice tasks
- Wrap
int.parsein a function that throwsFormatExceptionwith a custom message includingraw. - Add a
finallyblock that increments aattemptCountvariable and assert it runs on success and failure.