2011-08-07 12 views
17

Chcę być w stanie wysyłać sobie wszystkie błędy javascript na stronie. Jestem programistą rozszerzeń, więc poniższe elementy kładą nacisk na upewnienie się, że dom jest gotowy przed wywołaniem wywołania.Pobierz wszystkie błędy javascript na obsługę błędów strony/javascript

Zbadałem, dodając niektóre funkcje do throw, aby również wysyłać lub wysyłać wyjątki, ale nie uznałem tego za możliwe.

1: Głównym rozwiązaniem do tego, obsługi window.onerror:

window.onerror = function(e, url, line){ 
    mailError('onerror: ' + e + ' URL:' + url + ' Line:' + line); 
    console.error('\nLine ' + line + ':'); 
    setTimeout(function(){retry();}, 100); //mainly useful in content scripts for extensions, 
    return true; 
} 

Może też trzeba zrobić to samo za pomocą jQuery:

$(window).error( 
    function(e, url, line){ 
    //handle error 
    } 
); 

Wadą tego jest to, że kod przestał działać.

Aby uniknąć błędów przerywających wykonywanie, najlepiej jest użyć wywołań zwrotnych, aby upewnić się, że kod wykonywany jest w określonej kolejności i aby wykorzystywać zdarzenia w miarę możliwości. Można również chronić połączeń DOM za pomocą kilku technik

$(document).ready({ 
    //you usually won't get bad dom calls wrapping your code in this 
}); 

Można również rozważyć uruchomienie kodu na window.onload

window.onload = function(){ 
    //you page will probably twitch upon executing code at this time 
    //but you will almost never have a bad dom call 
}; 

Inną techniką

if (document.getElementById('iNeedThisElement')) { 
    //doin work! 
    document.getElementById('iNeedThisElement').style.display = 'block'; 
} else { 
    var stillNeedToTakeCareOfX = true; //false otherwise since it's undefined 
    mailError('iNeedThisElement was unavailable...'); 
} 

Korzystanie z tych technik i tylko debugowania wniosku, powinieneś być dość dobrze. Od console.error, .warn i .log oświadczenia nie może zostać odzyskane i zgłoszone do Twojej, mała alternatywa apartament znajduje się poniżej:

var Xe = { }; //Extreme error suite 

function extraInfo(e){ 
    //e optional 
    if(!e)e = true; 

    //add an extra debug info, such as navigator or current URL 
    return ' currentURL: '+ document.URL + 
     '\n userAgent: ' + navigator.userAgent + 
     '\n platform: ' + navigator.platform + 
     '\n userid: ' + localStorage.userid + 
     '\n language: ' + navigator.langauge + 
     '\n cookies?: ' + navigator.cookiesEnabled; 
} 

Xe.error = function(e){ 
    console.error(e); //maintain original functionality 
    mailError('Xe err: ' + e + extraInfo()); 
} 


Xe.warn = function(e){ 
    console.warn(e); 
    mailError('Xe warn: ' + e + extraInfo()); 
} 


Xe.log = function(e){ 
    console.log(e); 
    mailError('Xe log: ' + e + extraInfo()); 
} 

W rowie ostatniej można nieustannie próbować wykonać kawał kod, dopóki nie zostanie wykonany bez błędów. To jest "2" poniżej.

2: kod grupy w dużych kawałkach i próbuje ponownie wykonać x sekund później po połowu błąd, czy nadal następnym fragmencie kodu

//defExe = DEFinitely EXEcute this code 
    //functionArg, reference to a function holding a large chunk of code 
    //seconds, timeout in milliseconds to re-attempt error free execution of this function 
function defExe(functionArg, seconds) { 
    //seconds is optional 
    if (!seconds)seconds = 300; 

    try { 
    functionArg(); 
    } catch(e) { 
    //mail the error plus extra info 
    mailError('caught ' + e + ' attempting to re-execute ' + functionArg.name + ' in ' + seconds + ' milliseconds'); 

    //re-attempt to execute this code 
    setTimeout(function(){ 
     defExe(functionArg, seconds); 
    }, seconds); 
    } 
} 

ten jest następnie używany jak

//array to group function chunks 
var fn = [ ]; 

fn[1] = function(){ 
    //a large chunk of javascript 
} 
defExe(fn[1]); 

fn[2] = function(){ 
    //another chunk of your program 
} 
defExe(fn[2]); 

# 2 Podsumowanie: Grupowanie kodu w funkcjach i uruchamianie w bloku try-catch, powtarzanie w przypadku złapania błędów

+0

Wiesz, że 'fn.1' to nieprawidłowa syntaktyka? Musisz użyć 'fn [1]'. – HoLyVieR

+0

Tak naprawdę myślę, że odkryłem, że to, co chcę zrobić, to wykorzystać dostępne wydarzenie YUI, uruchamiane, gdy "DOM zareaguje na getElementById" http://developer.yahoo.com/yui/3/event/#onavailable Teraz muszę tylko utworzyć bardziej zaawansowaną funkcję doc.byI, która owija wywołania domowe w tej funkcji kodu YUI. Mogę jednak stracić błąd, a więc nie dowiedzieć się o kodzie, który jeszcze nie został uruchomiony. –

Odpowiedz

31

Mam pracę z window.onerror i nie zatrzymuje mojego javascript:

window.onerror = function(error, url, line) { 
    controller.sendLog({acc:'error', data:'ERR:'+error+' URL:'+url+' L:'+line}); 
}; 

Należy zauważyć, że controller.sendLog jest funkcją, która wysyła te dane do php do logowania.

Może być tak, ponieważ powodujesz pewien błąd javascript w tej funkcji?

+0

Podłączyłem kod do zwykłej strony i stwierdziłem, że wykonanie zostało zatrzymane, czy jesteś w specjalnym środowisku? Prawdopodobnie rozwój rozszerzenia? –

+4

Cóż, to zatrzyma wykonywanie bieżącego wątku, ponieważ powoduje błąd, to normalne zachowanie w javascript. Na stronie, której używam, mam wiele obiektów i zdarzeń wyzwalających tu i tam, więc jeśli się zepsuje, przestanie się to dziać, ale nowe zdarzenie wyzwalające ten sam kod znów działa. Myślę, że nie możesz tego uniknąć, jedynym sposobem na to jest użycie wielu bloków try-catch, a także, w bloku try-catch zachowanie jest takie samo, przestaje wykonywać blok i wskakuje do złapać zdanie. –

+0

Przyjęłam odpowiedź Sergiego, ponieważ pokazał on użycie parametrów adresu URL i linii, o których nie wiedziałem lub których nie używam powyżej –

2

Gdy wyjątek zostanie zgłoszony w większości języków, wykonanie bieżącego stosu poleceń zostanie zatrzymane. Więc twoje globalne podejście window.onerror działa, ale nie kontynuuje wykonywania kodu po awarii. Ciekawi mnie, dlaczego spodziewałbyś się ponowienia próby działania w przypadku niepowodzenia pierwotnego połączenia? Być może istnieje inny sposób na zoptymalizowanie aplikacji, aby tego uniknąć.

Jedną z rzeczy, które lubię robić, to zawijanie dowolnego kodu w funkcji window.onerror w bloku catch catch. W oświadczeniu o połowach (w ostateczności) generalnie użyję jakiegoś alarmu, na wypadek, gdyby coś poszło katastrofalnie nie tak. Pomysł polega na tym, że nie chcesz, aby obsługa błędów powodowała, że ​​strona KIEDYKOLWIEK zakończyła się, powodując pojawienie się kolejnego błędu.

+0

Dobra rada w oczekiwaniu na późniejszy kod. Domyślam się, że głównym celem było wyodrębnienie fragmentów kodu i otrzymanie większej ilości błędów odesłanych z powrotem. Powodem, dla którego mógłbym oczekiwać, że zadziała później, jest to, że w rozwoju rozszerzeń, czasami skrypty zawartości mogą działać zbyt wcześnie/szybko, dlatego czekanie trochę pozwoli stronie ładować więcej i powiedzieć obciążenia elementów DOM, które nie były wcześniej załadowany. –

+0

Poza tym może się skończyć czekaniem, aż sieć zostanie ponownie połączona. –

0

Można spróbować również

try ... catch

try 
{ 
    //Run your code here 
} 
catch(err) 
{ 
    //Handle the errors here 
} 
+0

To przyniesie działanie z błędami konsoli, chyba że zastąpisz funkcję błędu, aby zamiast tego podać błąd jako wyjątek: 'console.error = error => {throw Błąd (błąd)}; 'choć jest to raczej zła praktyka. –

3

Niestety ale try/catch złapie tylko błędy kodu, nigdy załadować błąd (jeśli brakuje pliku lub coś).

window.onerror/$ (okno) .error jest zdecydowanie najlepszym rozwiązaniem.

Powiązane problemy