Come posso riproporre un'eccezione in Javascript, ma preservare lo stack?


151

In Javascript, supponiamo di voler eseguire alcune operazioni di pulizia quando si verifica un'eccezione, ma lascia che l'eccezione continui a propagarsi nello stack, ad esempio:

try {
  enterAwesomeMode();
  doRiskyStuff(); // might throw an exception
} catch (e) {
  leaveAwesomeMode();
  throw e;
}
doMoreStuff();
leaveAwesomeMode();

Il problema con questo codice è che la cattura e la ricodificazione dell'eccezione causa la perdita delle informazioni della traccia dello stack fino a quel punto, in modo tale che se l'eccezione viene successivamente catturata nuovamente, più in alto nello stack, la traccia dello stack scende solo al re -gettare. Questo fa schifo perché significa che non contiene la funzione che ha effettivamente generato l'eccezione.

A quanto pare, try..finally ha lo stesso comportamento, almeno in Chrome (ovvero, non è proprio il rilancio che è il problema, ma la presenza di qualsiasi blocco del gestore delle eccezioni).

Qualcuno conosce un modo per ricodificare un'eccezione in Javascript ma preservare la traccia dello stack ad essa associata? In caso contrario, che ne dite di suggerimenti su altri modi per aggiungere gestori di pulizia sicuri dalle eccezioni, acquisendo al contempo tracce complete dello stack quando si verifica un'eccezione?

Grazie per eventuali suggerimenti :)


Risposte:


78

Questo è un bug in Chrome. La ripetizione di un'eccezione dovrebbe preservare la traccia della chiamata.

http://code.google.com/p/chromium/issues/detail?id=60240

Non conosco alcuna soluzione alternativa.

Finalmente non vedo il problema. Vedo eccezioni che non si presentano silenziosamente sulla console degli errori in alcuni casi dopo finalmente, ma quello sembra essere stato risolto nelle build di sviluppo.


5
Da allora questo problema è stato chiuso.
Zachary Burns,

24

La proprietà stack di un oggetto Error viene creata contemporaneamente all'oggetto Error stesso, non nel punto in cui viene generata. Spesso sono uguali a causa del linguaggio

   genera un nuovo errore ("messaggio");

e se si utilizza il codice così come è stato scritto, la proprietà dello stack non verrà modificata quando si ricodifica l'errore.


5
Questo non è vero (forse dipende dalla piattaforma). Il motore js che sto utilizzando ora (Rhino) ripristina la pila sull'istruzione di lancio, perdendo la pila originale.
Ted Bigham,

1
Forse è così, ma rhino-1.7.7.2.jar non lo modifica. Quale versione stai usando?
Mike, resta il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.