Ce face try, catch și finally
Codul care poate arunca o excepție se pune în blocul try. Dacă apare o excepție, Dart sare la prima clauză care o acceptă. on Tip prinde doar excepțiile de acel tip; catch (e) îți dă obiectul excepției; le poți combina: on FormatException catch (e). Un catch (e) fără on prinde orice.
catch (e, s) primește și al doilea parametru, stiva de apeluri (StackTrace), utilă la jurnalizare. Clauzele se verifică de sus în jos, deci pune tipurile specifice înaintea celor generale.
finally rulează întotdeauna la final: când blocul try se termină normal, când s-a prins o excepție și chiar când excepția nu a fost prinsă sau ai ieșit cu return. Acolo se eliberează resursele (fișiere, conexiuni).
Exemple
Exemplul 1: on și catch pe tipuri diferite
int.parse aruncă FormatException pentru text; împărțirea întreagă la zero aruncă UnsupportedError.
int imparte(String a, String b) => int.parse(a) ~/ int.parse(b);
void main() {
for (final (a, b) in [('100', '4'), ('zece', '2'), ('7', '0')]) {
try {
print('$a / $b = ${imparte(a, b)}');
} on FormatException catch (e) {
print('Nu este număr: ${e.source}');
} on UnsupportedError {
print('Nu se poate împărți la zero.');
}
}
}
Rezultat
100 / 4 = 25
Nu este număr: zece
Nu se poate împărți la zero.
Exemplul 2: finally rulează mereu
Mesajul din finally apare și după succes, și după eroare.
void proceseaza(String fisier) {
print('deschid $fisier');
try {
if (fisier.endsWith('.exe')) throw const FormatException('tip de fișier nepermis');
print('procesez $fisier');
} on FormatException catch (e) {
print('eroare: ${e.message}');
} finally {
print('închid $fisier');
}
}
void main() {
proceseaza('note.csv');
proceseaza('virus.exe');
}
Rezultat
deschid note.csv
procesez note.csv
închid note.csv
deschid virus.exe
eroare: tip de fișier nepermis
închid virus.exe
Exemplul 3: catch general și stiva de apeluri
catch (e, s) prinde orice; afișăm tipul și primul rând din stivă.
void citesteElement(List<String> lista, int poz) {
print(lista[poz]);
}
void main() {
try {
citesteElement(['Ana', 'Ion'], 5);
} catch (e, s) {
print('Prins: ${e.runtimeType}');
print('Mesaj: $e');
print('Primul rând din stivă: ${s.toString().split('\n').first}');
}
}
Rezultat
Prins: RangeError
Mesaj: RangeError (length): Invalid value: Not in inclusive range 0..1: 5
Primul rând din stivă: #0 List.[] (dart:core-patch/growable_array.dart)
Greșeli frecvente
catch (e)gol, care ascunde toate erorile: problemele nu mai apar nicăieri. Tratează sau măcar afișează excepția.- Clauza generală înaintea celei specifice:
catch (e)pus primul prinde tot, iaron FormatExceptionde sub el nu mai rulează niciodată. returnînfinally: înlocuiește valoarea returnată dintryși înghite excepția.
Comenzi înrudite
throw: Aruncă o excepție sau o eroare care oprește execuția normală până o prinde un catch.rethrow: Aruncă mai departe excepția prinsă în catch, păstrând stiva de apeluri originală.async și await: async marchează o funcție asincronă (întoarce Future), iar await așteaptă rezultatul unui Future fără să blocheze programul.