StackTrace în Dart

Lista apelurilor de funcții active într-un moment (cine pe cine a apelat), folosită pentru a găsi locul unei erori.

Sintaxă
abstract interface class StackTrace
static StackTrace get current
// prins cu: catch (e, st)

Ce face StackTrace

Un StackTrace descrie „drumul” până la un anumit punct din program: funcția curentă, funcția care a apelat-o și așa mai departe, până la main, fiecare cu fișierul și rândul. Îl primești ca al doilea parametru în catch (e, st), iar pentru erori și în câmpul Error.stackTrace.

StackTrace.current returnează stack trace-ul locului unde este apelat, fără să fie nevoie de o eroare. Este util pentru jurnale de depanare („de unde a fost apelată funcția asta?”).

Singura operație utilă pe un StackTrace este toString(), care dă textul pe mai multe rânduri. Formatul exact diferă între platforme (VM, web), deci nu-l prelucra în cod; scrie-l într-un jurnal. Pentru a arunca o eroare cu un stack trace păstrat vezi Error.throwWithStackTrace.

Ce returnează

current: un StackTrace.

Exemple

Exemplul 1: Prinderea stack trace-ului

Afișăm doar numele funcțiilor găsite în stack trace; textul complet conține căi de fișiere de pe calculatorul care rulează.

int calculeazaMedia(List<int> note) => note.reduce((a, b) => a + b) ~/ note.length;

String raportElev(String nume, List<int> note) => '$nume: ${calculeazaMedia(note)}';

void main() {
  try {
    print(raportElev('Ana', [9, 10]));
    print(raportElev('Mihai', []));
  } on StateError catch (e, st) {
    print('Eroare: ${e.message}');
    for (var f in ['calculeazaMedia', 'raportElev', 'main']) {
      print('$f în stack trace: ${st.toString().contains(f)}');
    }
  }
}

Rezultat

Ana: 9
Eroare: No element
calculeazaMedia în stack trace: true
raportElev în stack trace: true
main în stack trace: true

Exemplul 2: StackTrace.current pentru depanare

Primul rând din StackTrace.current este chiar funcția care l-a cerut. Rezultatul este scurtat; calea fișierului diferă de la un calculator la altul.

void jurnal(String mesaj) {
  var linii = StackTrace.current.toString().split('\n');
  print('$mesaj\n  apelat din: ${linii[1]}');
}

void salveazaComanda() {
  jurnal('Salvez comanda #1024');
}

void main() {
  salveazaComanda();
}

Rezultat posibil (diferă la fiecare rulare)

Salvez comanda #1024
  apelat din: #1      salveazaComanda (file:///home/ana/proiect/main.dart:7:3)

Greșeli frecvente

  • Afișezi stack trace-ul complet utilizatorilor aplicației. Este pentru programatori; arată-l doar în jurnale.
  • Scrii catch (e) și apoi cauți stack trace-ul. Cere-l explicit: catch (e, st).

Comenzi înrudite

  • Error: Clasa de bază pentru greșelile de programare (index greșit, argument invalid); stackTrace arată unde a fost aruncată.
  • Error.throwWithStackTrace: Aruncă un obiect împreună cu un StackTrace dat, de exemplu cel al erorii originale, ca să nu se piardă locul inițial.
  • try, catch și finally: try prinde excepțiile din bloc; on alege tipul, catch dă acces la obiect, finally rulează mereu.