爲了使調試更容易,我在Chrome中捕獲所有控制檯日誌,以便提交反饋條目的用戶也將所有日誌提交到我們的服務器。當有人在生產中遇到問題時,我可以首先讓他們重新工作,這樣我就可以坐下來更徹底地查看所有日誌,以確定用戶在生產中遇到的任何問題的根本原因。如何在Chrome的JavaScript中重寫/擴展ReferenceError?
我用來捕獲日誌的技術涉及覆蓋console.log,以便在第一個參數中輸入的所有文本都存儲在數組中,同時調用遺留函數,以便我仍然可以在控制檯中看到日誌。
問題是當偶爾有未捕獲的異常。這些不包含在上傳的日誌中,因此並不總是清楚導致問題的原因。所以我試着通過編寫一個以函數作爲參數的JavaScript函數來覆蓋ReferenceError,然後返回一個新的函數來處理它,比如將數據存儲在變量中,然後調用傳統函數作爲最後一步:
function overrideException(legacyFn) {
/** arguments for original fn **/
return function() {
var args = [];
args[0] = arguments[0];
// pass in as arguments to original function and store result to
// prove we overrode the ReferenceError
output = ">> " + legacyFn.apply(this, args).stack;
return legacyFn.apply(this, arguments);
}
}
要測試overrideException功能,我跑在控制檯上下面的代碼:
ReferenceError = overrideException(ReferenceError);
後來,我通過手動拋出的ReferenceError測試返回的功能,新的ReferenceError,:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
在控制檯上的輸出結果是:
ReferenceError: YES!! IT WORKS! HAHAHA!
而且檢查從overrideException功能全局變量output
表明,它確實運行:
output
">> ReferenceError: YES!! IT WORKS! HAHAHA!
at ReferenceError (<anonymous>)
at new <anonymous> (<anonymous>:18:35)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
at Object.InjectedScript.evaluate (<anonymous>:440:21)"
現在,這裏的事情開始下降分開。在我們的代碼,我們沒有嘗試運行了一個不存在的函數去時未捕獲的異常發生時就知道了,所以我測試了它:
ttt();
導致:
ReferenceError: ttt is not defined
但是,與我們明確拋出錯誤的情況不同,在這種情況下,函數不會觸發,而我們只剩下遺留功能。變量output
的內容與第一個測試中的內容相同。
所以這個問題似乎是這樣的:我們如何重寫JavaScript引擎用來引發錯誤的ReferenceError功能,以便在我們拋出ReferenceError時使用它?
請記住,我的問題目前僅限於Chrome;我正在構建Chrome Packaged應用。
猜測你不想將代碼包裝在try/catch中,然後處理錯誤對象然後重新拋出? –
@瘋狂火車 - 我可以做到,我可能會。然而,這是乏味的,也可能會錯過一些東西。我喜歡防僞和全包的解決方案,因爲它們通常也是「我太忙了」。:)我的計劃當然是使用更多的嘗試/捕獲,但這似乎是一個很好的解決方案,所以我開始深入研究它。 – jmort253
我的意思是一個單一的'try/catch'包裝所有的代碼。由於看起來目標並不是處理錯誤,而是以某種方式重新格式化它,然後將所有代碼包裝在一個'try/catch'中看起來與您當前的替換構造函數的方法有所不同。你只需要確定你重新拋出你得到的任何錯誤。 –