Ce face throw
throw oprește funcția curentă și „aruncă” un obiect în sus, prin funcțiile care au apelat-o, până îl prinde un try-catch. Dacă nu îl prinde nimeni, programul se oprește și afișează mesajul și stiva de apeluri.
Dart face diferența între Exception (situații așteptate, pe care programul le poate trata: fișier lipsă, format greșit) și Error (greșeli de programare: ArgumentError, StateError, RangeError). Poți arunca orice obiect nenul, dar convenția este să arunci clase care implementează Exception sau extind Error.
throw este o expresie, deci poate sta după => sau după ??: final nume = argument ?? (throw ArgumentError('lipsește numele'));.
Exemple
Exemplul 1: Validarea unui argument
Funcția aruncă ArgumentError pentru o sumă negativă; în main o prindem.
double aplicaReducere(double pret, double procent) {
if (procent < 0 || procent > 100) {
throw ArgumentError('procent invalid: $procent');
}
return pret * (1 - procent / 100);
}
void main() {
print(aplicaReducere(200, 15));
try {
aplicaReducere(200, 120);
} on ArgumentError catch (e) {
print('Eroare: ${e.message}');
}
}
Rezultat
170.0
Eroare: procent invalid: 120.0
Exemplul 2: Excepție proprie
O clasă care implementează Exception, cu un toString clar.
class StocInsuficient implements Exception {
final String produs;
final int cerut, disponibil;
StocInsuficient(this.produs, this.cerut, this.disponibil);
@override
String toString() => 'StocInsuficient: $produs (cerut $cerut, în stoc $disponibil)';
}
final stoc = {'mere': 10, 'pere': 2};
void comanda(String produs, int bucati) {
final disponibil = stoc[produs] ?? 0;
if (bucati > disponibil) throw StocInsuficient(produs, bucati, disponibil);
stoc[produs] = disponibil - bucati;
print('Comandă acceptată: $bucati $produs');
}
void main() {
for (final (p, n) in [('mere', 3), ('pere', 5)]) {
try {
comanda(p, n);
} on StocInsuficient catch (e) {
print(e);
}
}
}
Rezultat
Comandă acceptată: 3 mere
StocInsuficient: pere (cerut 5, în stoc 2)
Exemplul 3: throw ca expresie
throw stă după ?? și după =>.
String cere(Map<String, String> config, String cheie) =>
config[cheie] ?? (throw StateError('lipsește setarea "$cheie"'));
void main() {
final config = {'oras': 'Oradea'};
print(cere(config, 'oras'));
try {
cere(config, 'port');
} on StateError catch (e) {
print(e.message);
}
}
Rezultat
Oradea
lipsește setarea "port"
Greșeli frecvente
throw 'text';: este permis, dar unStringnu are tip specific de prins și nici stivă clară. Aruncă o clasă de excepție.- Să prinzi
Error-uri (greșeli de programare) ca pe excepții normale: de obicei trebuie reparat codul, nu ascunsă eroarea. - Pentru a arunca mai departe excepția prinsă, folosește
rethrow, nuthrow e: păstrezi stiva originală.
Comenzi înrudite
try, catch și finally: try prinde excepțiile din bloc; on alege tipul, catch dă acces la obiect, finally rulează mereu.rethrow: Aruncă mai departe excepția prinsă în catch, păstrând stiva de apeluri originală.assert: Verifică o condiție în timpul dezvoltării; în producție și la dart run implicit, assert este ignorat.