Error handling
- Dart course
- Beginner
- Lesson 115/116
- 6 min
Add error handling with try/catch.
Error handling
If you call a non-existent index on a list Dart throws a RangeError. The program crashes on that error. But with try/catch you catch the error and show a friendly message; the program keeps running.
For example on a two-book list calling books[5] throws. With try { print(books[5].title); } catch (e) { print("book not found"); } you catch the error and show a friendly message. This is what makes real applications resilient; unexpected cases become a friendly reply instead of a crash.
The try/catch pattern
In this project we use try/catch in this case: the user asks for a book number, the number is not in the list, a RangeError is thrown. catch catches it and prints "book not found". So the program keeps running even when a book is missing.
A good application is resilient to errors. Alongside try/catch you sometimes also do an explicit if (index < books.length) check; this prevents the error up front. Which one to pick depends on the case. try/catch is more general; if is more explicit. We will try try/catch in this lesson.
Practice Catch an out-of-range access
The Library and Book classes plus a two-book list are already defined in the code below. Inside a try block call print(books[5].title); this throws an out-of-range error. In a catch (e) block print "book not found". The program gives a message instead of crashing.
Starter code
class Library {
String name;
Library(this.name);
void info() {
print("Library: $name");
}
}
class Book {
String title;
Book(this.title);
}
void main() {
final lib = Library("City");
lib.info();
final b = Book("Crime and Punishment");
print("New book: ${b.title}");
final books = <Book>[Book("Crime and Punishment"), Book("Les Mis")];
print("Count: ${books.length}");
print("First: ${books[0].title}");
// try the index 5 access; print a message in catch
}Sample solution
class Library {
String name;
Library(this.name);
void info() {
print("Library: $name");
}
}
class Book {
String title;
Book(this.title);
}
void main() {
final lib = Library("City");
lib.info();
final b = Book("Crime and Punishment");
print("New book: ${b.title}");
final books = <Book>[Book("Crime and Punishment"), Book("Les Mis")];
print("Count: ${books.length}");
print("First: ${books[0].title}");
try {
print(books[5].title);
} catch (e) {
print("book not found");
}
}Expected output
Library: City New book: Crime and Punishment Count: 2 First: Crime and Punishment book not found
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Match error handling
| Term | Meaning |
|---|---|
RangeError |
out-of-range access |
try |
holds risky code |
catch |
catches the error |
print |
writes the message |
2 When does control leave the try block?
try {
print(books[5].title);
} catch (e) {
print("none");
}- When an error is thrown
- When print runs
- When main starts
- Never Correct answer
Explanation: an error inside try passes control to catch.
3 The catch block
try {
print(books[5].title);
} ____ (e) {
print("no book");
}
try {
print(books[5].title);
} catch (e) {
print("no book");
}
Explanation: Write catch; followed by (e) parameter and block.