2011-02-10 171 views
0

我想記錄瀏覽器端JavaScript代碼中的所有錯誤。我在這裏和網上看到了很多關於window.onerror的討論,很明顯它不能跨瀏覽器工作。所以,我打算用try-catch來包裝頂層輸入函數。麻煩的是,我的很多代碼都是事件處理程序。我還沒有測試過它,但我確信無論事件處理函數是在哪裏定義的,拋出的錯誤都會直接觸發調用它的瀏覽器實現,而不是事件函數聲明代碼。我唯一的選擇是在每個錯誤處理程序中聲明拋出,捕獲和錯誤日誌調用,即使是最小的匿名調用。我不喜歡那一點。事件處理程序的全局錯誤日誌記錄javascript

一種可能的解決方案:

我使用一種方法越過瀏覽器寄存器的事件。我可以修改它來做這樣的事情:

function registerEventHandler(object, handlerRef) { 
    var wrapperFunction = function(evt) { 
    try {   
    handlerRef(evt); 
    } catch { 
    logError(error); 
    } 
    registerEvent(object, wrapperFunction); 
} 

這個實現有一個主要問題。我經常保留對事件處理函數的引用,以便稍後註銷它們。這將不起作用,因爲註冊爲處理函數的函數將是包裝器,而不是原始包裝器。對此的答案是實現一個包裝 - >包裝映射對象,並在取消註冊時使用它。

問題:

我敢說你的JavaScript魔術師拿出比這更聰明的解決方案。也許這可以通過在註冊之前以某種方式增強事件處理函數來完成?這是我的JavaScript知識。你呢?

回答

1

我經常保持對事件 處理函數的引用,以 後來註銷它們。這將不會 工作,因爲註冊爲 處理程序的函數將是包裝程序,而不是原來的 。

爲什麼這是一個問題?一旦函數被包裝在錯誤處理中,你就不再關心原始函數了。包裝器保持對原始函數的引用,並且包裝器是註冊的,而包裝器是需要註銷的東西。

只保留一個引用到你生成的包裝函數,因爲它是唯一重要的。


,也使其它自己的功能將使這一模式更可重複使用的

var protectErrors = function(fn) { 
    var that = this; 
    return function() { 
    try { 
     fn.apply(that, arguments); 
    } catch(error) { 
     logError(error); 
    } 
    }; 
}; 

var registerEventHandler = function(object, handlerRef) { 
    var wrapperFunction = protectErrors(handlerRef); 
    registerEvent(object, wrapperFunction); 
}; 

protectErrors(fn)將返回運行原來在任何情況下,它被稱爲一個功能,並轉發任意數量的參數。

+0

這是一個問題沒有太大的問題,它只是更多的開銷。我不想要它,我可以幫助它。 – 2011-02-10 08:43:18