Future.catchError în Dart

Prinde eroarea unui future și o înlocuiește cu o valoare de rezervă (echivalentul lui catch pentru lanțuri then).

Sintaxă
Future<T> catchError(Function onError, {bool test(Object error)?})

Ce face Future.catchError

catchError returnează un future nou. Dacă future-ul inițial reușește, valoarea trece mai departe neschimbată. Dacă se termină cu eroare, se cheamă onError, iar ce returnează acesta devine valoarea noului future.

Funcția onError poate primi doar eroarea, sau eroarea și StackTrace-ul. Cu test poți prinde doar anumite erori; celelalte trec mai departe. În codul cu await același lucru se face cu try/on/catch.

Parametri

Parametru Descriere
onError Funcția care primește eroarea și returnează valoarea de rezervă (de același tip ca future-ul).
test Opțional: alege ce erori se prind.

Ce returnează

Un Future<T> cu valoarea originală sau cu valoarea de rezervă.

Exemple

Exemplul 1: Valoare de rezervă la eroare

Future<int> stocDinServer(String produs) async {
  await Future.delayed(const Duration(milliseconds: 10));
  if (produs == 'cafea') return 12;
  throw StateError('serverul nu răspunde');
}

Future<void> main() async {
  for (final p in ['cafea', 'ceai']) {
    final stoc = await stocDinServer(p).catchError((Object e) {
      print('  ($p) eroare: $e');
      return 0;
    });
    print('$p: $stoc bucăți');
  }
}

Rezultat

cafea: 12 bucăți
  (ceai) eroare: Bad state: serverul nu răspunde
ceai: 0 bucăți

Exemplul 2: Doar anumite erori, cu test

FormatException este prinsă de catchError; StateError nu trece testul și ajunge la try/catch.

Future<int> citesteVarsta(String text) async {
  if (text.isEmpty) throw StateError('câmp gol');
  return int.parse(text);
}

Future<void> main() async {
  for (final intrare in ['21', 'abc', '']) {
    try {
      final v = await citesteVarsta(intrare).catchError((Object e) => -1, test: (e) => e is FormatException);
      print('"$intrare" -> $v');
    } on StateError catch (e) {
      print('"$intrare" -> eroare netratată de catchError: ${e.message}');
    }
  }
}

Rezultat

"21" -> 21
"abc" -> -1
"" -> eroare netratată de catchError: câmp gol

Greșeli frecvente

  • Returnezi din onError o valoare de alt tip decât future-ul (de exemplu null pentru un Future<int>). La rulare apare o eroare de tip.
  • Pui catchError înaintea lui then și te aștepți să prindă erorile din then. Prinde doar erorile de dinaintea lui în lanț.

Comenzi înrudite

  • Future.then: Înregistrează o funcție care primește valoarea future-ului când e gata și returnează un future nou cu rezultatul ei.
  • Future.whenComplete: Rulează o funcție când future-ul se termină, fie cu succes, fie cu eroare (echivalentul lui finally).
  • Future.value: Future.value creează un future deja terminat cu o valoare, iar Future.error unul terminat cu o eroare.
  • try, catch și finally: try prinde excepțiile din bloc; on alege tipul, catch dă acces la obiect, finally rulează mereu.
  • runZonedGuarded: Rulează cod într-o zonă nouă și prinde toate erorile asincrone netratate din ea, cu o singură funcție.