2011-08-07 75 views
17

我希望能夠發送一個頁面上的所有javascript錯誤。我是一個擴展開發人員,所以下面的重點是確保在調用dom之前準備好dom。獲取頁面上的所有javascript錯誤/ javascript錯誤處理

我調查了爲throw添加一些功能來發送或郵寄異常,但我沒有發現這是可能的。

1:主要解決了這一點,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; 
} 

可能還需要通過jQuery做同樣的事情:

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

這樣做的垮臺是你的代碼已停止執行。

爲了避免錯誤停止執行,最好使用回調來確保代碼以特定順序執行,並儘可能地利用事件。您也可以保護DOM調用與

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

您也可以考慮在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 
}; 

另一種技術

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...'); 
} 

運行代碼中使用這些技術的一些技巧,只是調試應用程序,你應該相當順利。由於console.error,.warn,和.log語句不能被檢索並報告給你的,一個小的替代套件提供如下:

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()); 
} 

作爲最後一搏,你可以不斷嘗試執行的一大塊代碼直到執行沒有錯誤。這是下面的「2」。

2:在大塊組代碼,並試圖以後捕獲錯誤後重新執行x秒,或繼續的代碼下一個塊

//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); 
    } 
} 

此它然後被用於像

//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摘要:組函數中的代碼並在try-catch塊中運行,如果發生錯誤,則重複執行

+0

你知道'fn.1'是無效的synthax?你需要使用'fn [1]'。 – HoLyVieR

+0

所以實際上我想我已經發現我想要做的是使用YUI可用事件,當「DOM響應getElementById」時觸發http://developer.yahoo.com/yui/3/event/#onavailable 現在我只需要製作一個更精通的doc.byId函數,它可以在此YUI代碼功能中封裝dom調用。但是,我可能會失去一個錯誤,從而無法找出尚未運行的代碼。 –

回答

31

我有我的window.onerror,它不會停止我的javascript:

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

請注意,controller.sendLog是一個函數,它將這些數據發送到日誌記錄php。

可能是因爲你在該函數內導致一些JavaScript錯誤?

+0

我把你的代碼插入一個普通的頁面,發現執行停止,你是在一個特殊的環境?可能的擴展開發? –

+4

那麼,它會停止執行當前線程,因爲它遇到了錯誤,這是javascript中的正常行爲。在我使用這個頁面中,我有很多對象和事件在這裏和那裏觸發,所以如果一箇中斷,那麼一個停止執行,但一個新事件觸發相同的代碼再次工作。我認爲你不能避免它停止,唯一的方法就是使用大量的try-catch塊,並且在try-catch塊中的行爲是一樣的,它會停止執行塊並跳轉到抓句子。 –

+0

我接受了Sergi的答案,因爲他顯示了我不知道的或使用的 –

2

當大多數語言引發異常時,當前命令堆棧的執行將被停止。因此,您的全局window.onerror方法有效,但在失敗後不會繼續執行代碼。我很好奇爲什麼你會希望在原來的呼叫失敗的情況下重試工作?也許還有另一種方法來優化您的應用程序以避免這種情況。

我喜歡做的事情之一是將我的任何代碼包裝在try catch塊中的window.onerror函數中。在catch語句中(最後的手段),我通常會使用某種類型的警報,以防萬一出現災難性錯誤。這裏的想法是,你不希望你的頁面錯誤處理最終導致另一個錯誤被啓動。

+0

期待代碼稍後成功的好處。 我猜這個主要目標是隔離代碼塊並獲得更多郵寄回來的錯誤。 我之後可能會期望它的工作原因是,在擴展開發中,有時內容腳本可能運行得太早/很快,因此稍等一會就會允許頁面加載更多並說加載之前沒有的DOM元素加載。 –

+0

除此之外,它最終可能會等待網絡重新連接 –

0

你可以嘗試也

try ... catch語句

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

這不會與控制檯錯誤一起工作,除非您覆蓋錯誤函數以將錯誤作爲異常拋出:'console.error = error => {throw錯誤(錯誤)};'雖然這是一個相當糟糕的做法。 –

3

很抱歉,但try/catch語句將只捕獲代碼中的錯誤,從來不加載錯誤(如果文件丟失或東西)。

window.onerror/$(window).er​​ror絕對是最好的解決方案。