Introduction
The finally block always executes after try and catch, regardless of whether an exception was thrown or caught. It is ideal for cleanup code — closing connections, releasing resources, logging completion.
try {
// risky code
} catch (e) {
// handle error
} finally {
// ALWAYS runs
}
Execution Guarantee
void demonstrate(bool throwError) {
print('Start');
try {
if (throwError) throw Exception('Oops!');
print('No error occurred');
} catch (e) {
print('Caught: $e');
} finally {
print('Finally always runs');
}
print('After try-catch-finally');
}
void main() {
demonstrate(false);
print('---');
demonstrate(true);
}
Output:Start
No error occurred
Finally always runs
After try-catch-finally
---
Start
Caught: Exception: Oops!
Finally always runs
After try-catch-finally
Finally with Return
The finally block runs even when a return statement is encountered inside try:
int divide(int a, int b) {
try {
print('Dividing $a by $b');
return a ~/ b;
} catch (e) {
print('Error: $e');
return -1;
} finally {
print('Division attempt complete'); // always prints
}
}
void main() {
print(divide(10, 2)); // 5
print(divide(10, 0)); // -1
}
Resource Cleanup
class DatabaseConnection {
bool isOpen = false;
void open() {
isOpen = true;
print('Connection opened');
}
void close() {
isOpen = false;
print('Connection closed');
}
List<String> query(String sql) {
if (!isOpen) throw StateError('Connection is closed');
return ['row1', 'row2'];
}
}
void runQuery() {
var db = DatabaseConnection();
try {
db.open();
var results = db.query('SELECT * FROM users');
print('Results: $results');
} catch (e) {
print('Query failed: $e');
} finally {
db.close(); // always closes connection
}
}
void main() => runQuery();
🧠 Quiz
1. When does the finally block NOT execute?
- A) When no exception occurs
- B) When a return statement is hit in try
- C) When Dart.exit() is called ✅ (process terminates)
- D) When catch handles the exception
2. What is the primary use of the finally block?
- A) To re-throw exceptions
- B) To catch uncaught exceptions
- C) To release resources and cleanup ✅
- D) To log exceptions
Summary
The finally block always executes — after try, after catch, even after return. Use it to release resources like database connections, file handles, or network sockets. It runs regardless of whether an exception was thrown or handled.