Cum să înregistrați excepțiile în JavaScript (Programare, Javascript, Gestionarea Excepțiilor)

În calitate de dezvoltator C#, sunt obișnuit cu următorul stil de tratare a excepțiilor:

try
{
    throw SomeException("hahahaha!");
}
catch (Exception ex)
{
    Log(ex.ToString());
}

Output
------

SomeNamespace.SomeException: hahahaha!
    at ConsoleApplication1.Main() in ConsoleApplication1Program.cs:line 27

Este foarte simplu și totuși îmi spune tot ce trebuie să știu despre ce a fost excepția și unde a fost.

Cum pot realiza un lucru echivalent în JavaScript, unde obiectul excepției în sine poate fi doar un șir de caractere. Aș dori cu adevărat să pot ști exact linia de cod în care s-a produs excepția, însă următorul cod nu înregistrează nimic util:

try
{
    var WshShell = new ActiveXObject("WScript.Shell");
    return WshShell.RegRead("HKEY_LOCAL_MACHINE\Some\Invalid\Location");
}
catch (ex)
{
    Log("Caught exception: " + ex);
}

Output
------

Caught exception: [object Error]

EDITARE (din nou): Doar pentru a clarifica, aceasta este pentru o aplicație internă care utilizează intens JavaScript. Caut o modalitate de a extrage informații utile din erorile JavaScript care ar putea fi prinse în sistemul de producție – am deja un mecanism de logare, vreau doar o modalitate de a obține un șir de caractere sensibil pentru logare.

7 răspunsuri
Eldar Djafarov

Puteți utiliza aproape în același mod, adică.

try
{
    throw new Error("hahahaha!");
}
catch (e)
{
    alert(e.message)
}

Dar dacă doriți să obțineți numărul de linie și numele fișierului în care este aruncată eroarea presupun că nu există o soluție crossbrowser. Mesajul și numele sunt singurele proprietăți standard ale obiectului Error. În Mozilla aveți, de asemenea, proprietățile lineNumber și fileName.

Comentarii

  • Acest lucru nu funcționează pe server. De asemenea, nu este un UX modern. –  > Por Michael Cole.

Nu specificați dacă lucrați în browser sau pe server. Dacă este primul caz, există un nou console.error și proprietatea e.stack:

try {
    // do some crazy stuff
} catch (e) {
    console.error(e, e.stack);
}

Rețineți că error va funcționa pe Firefox și Chrome, dar nu este standard. Un exemplu rapid care va retrograda la console.log și va înregistra e în cazul în care nu există e.stack:

try {
    // do some crazy stuff
} catch (e) {
    (console.error || console.log).call(console, e.stack || e);
}

Comentarii

  • Singurul browser care nu are e.stack este IE 9 și mai vechi – acestea reprezintă mai puțin de 2% din cota de piață a browserelor, conform Net Marketshare. Cu siguranță nu am de gând să-mi fac griji în legătură cu suportul pentru aceste browsere – Microsoft a încheiat suportul extins pentru IE 8 cu mulți ani în urmă, așa că nu am nicio idee cine îl mai folosește. –  > Por ArtOfWarfare.

După cum subliniază Eldar, puteți folosi e.message pentru a obține mesajul de excepție. Cu toate acestea, în Chrome, Firefox și IE10+, puteți obține, de asemenea, urmărirea stivei folosind e.stack. Urma de stivă va include fișierul și numărul de linie al excepției.

Așadar, pentru a asambla un șir de caractere cu informații despre excepție, ar trebui să scrieți ceva de genul acesta:

var exmsg = "";
if (e.message) {
    exmsg += e.message;
}
if (e.stack) {
    exmsg += ' | stack: ' + e.stack;
}

Rețineți că veți obține o urmă de stivă numai dacă

  1. excepția a fost lansată de browser (de exemplu, ca răspuns la o eroare de sintaxă);
  2. obiectul de excepție este un obiect Error sau are ca prototip obiectul Error.

Deci, doar aruncând un șir de caractere (throw ‘Exception!!!’) nu veți obține o urmărire în stivă.

Pentru a merge un pic mai departe, pentru a prinde toate excepțiile neînregistrate, veți utiliza un manager window.onerror (similar cu managerul Application_Error din .Net Application_Error din global.asax). Dezavantajul acestui procedeu era (și în mare parte încă mai este) că nu vă permitea accesul la obiectul de excepție propriu-zis, deci nu puteați obține urmărirea stivei. Ați obține doar mesajul, adresa URL și numărul de linie.

Recent, standardul a fost extins pentru a vă oferi coloana (excelent pentru fișierele minificate) și obiectul excepției:http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#errorevent

În acest moment (aprilie 2014), doar Chrome 32 implementează toate acestea. IE10+ vă oferă coloana, dar nu și obiectul de excepție. Firefox 28 încă vă oferă doar mesajul, adresa URL și numărul liniei. Să sperăm că acest lucru se va îmbunătăți în curând. Am scris despre acest lucru pentru proiectul JSNLog, la:http://jsnlog.com/Documentation/GetStartedLogging/ExceptionLogging

(Disclaimer: eu sunt autorul JSNLog și jsnlog.com)

În al doilea rând, obiectul .Net Exception suportă excepții interioare. De asemenea, are o proprietate Data, astfel încât să puteți atașa perechi cheie-valoare cu, de exemplu, valori variabile. Mi-a cam lipsit acest lucru în obiectul JavaScript Error, așa că am creat propriul meu obiect Exception, tot ca parte a proiectului JSNLog. Acesta se află în fișierul jsnlog.js din proiectul Github jsnlog.js (https://github.com/mperdeck/jsnlog.js).

Descrierea se află la:http://jsnlog.com/Documentation/JSNLogJs/Exception

În cele din urmă, un plug-in nerușinat – proiectul JSNLog la care lucrez vă permite să inserați jurnaliști în JavaScript și inserează automat mesajele de jurnal în jurnalul existent pe partea serverului. Deci, pentru a înregistra excepțiile JavaScript cu urmele lor de stivă în jurnalul de pe partea serverului, trebuie doar să scrieți:

try {
    ...
} catch (e) {
    JL().fatalException("something went wrong!", e);
}

Comentarii

  • Știu Eu sunt cu 3 ani întârziere la petrecere…. dar sunt destul de sigur că, dacă arunci o excepție reală (nu doar un șir de caractere), vei obține acea urmă de stivă. De exemplu: throw new Exception('Exception!!');. –  > Por samson.
mahju

Nu sunt sigur dacă este sau nu cross browser sau dacă este ceea ce căutați, dar vă sugerez să încercați:

window.onerror = function (err, file, line) {
    logError('The following error occurred: ' + 
    err + '
In file: ' + file + '
On line: ' + line);
    return true;
}

Am avut o problemă similară.

Folosind console.table(error); a funcționat bine pentru mine. îmi afișează informațiile într-un tabel și, de asemenea, îmi permite să le extind/colapsez pentru a vedea mai multe detalii.

Quentin

Comentarii

  • Mă interesează cu adevărat să știu cum să extrag informații utile din excepție – mi-am reformulat întrebarea. –  > Por Justin.
Kirtan

Puteți utiliza instrumente de logare precum Yahoo! UI Library – Logger pentru a înregistra erorile/mesajele informative.