Ce face rethrow
rethrow; se poate scrie doar într-un bloc catch. El aruncă mai departe exact aceeași excepție, ca și cum nu ar fi fost prinsă, iar funcția care te-a apelat o poate trata.
Se folosește când vrei să faci ceva la apariția erorii (să scrii în jurnal, să anulezi o operație), dar decizia finală aparține altui nivel din program. Spre deosebire de throw e;, rethrow păstrează stiva de apeluri originală, deci vezi locul unde a apărut problema.
Poți combina: prinzi un tip, tratezi unele cazuri și faci rethrow pentru celelalte.
Exemple
Exemplul 1: Jurnalizare și aruncare mai departe
incarcaProfil scrie în jurnal, iar main decide ce afișează utilizatorului.
int citesteVarsta(String text) {
try {
return int.parse(text);
} on FormatException {
print('[jurnal] vârstă invalidă: "$text"');
rethrow;
}
}
void main() {
try {
print(citesteVarsta('23'));
print(citesteVarsta('douăzeci'));
} on FormatException catch (e) {
print('Utilizatorului: introdu un număr (${e.message})');
}
}
Rezultat
23
[jurnal] vârstă invalidă: "douăzeci"
Utilizatorului: introdu un număr (Invalid radix-10 number)
Exemplul 2: Tratezi unele cazuri, restul merg mai departe
Codul 404 este tratat local; celelalte erori sunt aruncate mai departe.
class EroareHttp implements Exception {
final int cod;
EroareHttp(this.cod);
@override
String toString() => 'EroareHttp $cod';
}
String descarca(String pagina) {
final coduri = {'acasa': 200, 'vechi': 404, 'admin': 403};
final cod = coduri[pagina] ?? 500;
if (cod != 200) throw EroareHttp(cod);
return 'conținutul paginii $pagina';
}
String descarcaSauGol(String pagina) {
try {
return descarca(pagina);
} on EroareHttp catch (e) {
if (e.cod == 404) return '(pagina nu mai există)';
rethrow;
}
}
void main() {
for (final p in ['acasa', 'vechi', 'admin']) {
try {
print(descarcaSauGol(p));
} on EroareHttp catch (e) {
print('Eroare netratată: $e');
}
}
}
Rezultat
conținutul paginii acasa
(pagina nu mai există)
Eroare netratată: EroareHttp 403
Exemplul 3: rethrow păstrează stiva originală
Stiva arată funcția calculeaza, unde a apărut eroarea, nu locul unde a fost aruncată din nou.
int calculeaza(List<int> v) => v[10];
int cuJurnal(List<int> v) {
try {
return calculeaza(v);
} catch (e) {
print('[jurnal] ${e.runtimeType}');
rethrow;
}
}
void main() {
try {
cuJurnal([1, 2, 3]);
} catch (e, s) {
final functii = s
.toString()
.split('\n')
.where((l) => l.contains('main.dart'))
.map((l) => l.split(RegExp(r'\s+'))[1]);
print('Stiva: ${functii.join(' <- ')}');
}
}
Rezultat
[jurnal] RangeError
Stiva: calculeaza <- cuJurnal <- main
Greșeli frecvente
rethrowîn afara unuicatch:A rethrow must be inside of a catch clause.throw e;în loc derethrow;: stiva începe din bloculcatch, iar locul real al erorii se pierde.- Prinderea și aruncarea mai departe fără să faci nimic: atunci
try-catchnu are rost.
Comenzi înrudite
try, catch și finally: try prinde excepțiile din bloc; on alege tipul, catch dă acces la obiect, finally rulează mereu.throw: Aruncă o excepție sau o eroare care oprește execuția normală până o prinde un catch.