IE10 Error.stack 讓指令碼調試更便捷

來源:互聯網
上載者:User
文章目錄
  • DOM 異常與 Error.stack
  • 效能注意事項
  • 非同步異常

  在IE10中已經新加入了Error.stack 的支援,可以加快開發人員的指令碼調試,並更正錯誤。尤其是一些難以重現的錯誤,如非同步作業等。以下內容來自於微軟IE團隊,對於這個特性描述的非常詳細。

 

調試應用程式

JavaScript 中的結構化錯誤處理依賴於 throwtry/catch,開發人員將在其中聲明一個錯誤,並將控制流程傳遞至處理錯誤的程式的某一部分。當某一錯誤被引發時,Chakra,即 Internet Explorer 中的 JavaScript 引擎將捕獲引發該錯誤的調用鏈,這一過程也被稱為呼叫堆疊。如果被引發的對象是一個 Error(或者是一個函數,且其原型鏈將導致 Error),那麼 Chakra 將建立一個堆疊追蹤,即可人工讀取的呼叫堆疊列表。該列表將被表示為一種屬性,即 Error 對象中的 stackstack 包含錯誤訊息、函數名稱和該函數的源檔案位置資訊。這些資訊將有助於開發人員瞭解所調用的函數,甚至查看錯誤的程式碼,從而迅速診斷缺陷。例如,這些資訊可能表明傳遞至函數的某一參數為空白,或為無效類型。

讓我們一同來查看一個簡單的指令碼,並以此展開深入討論。該指令碼試圖計算 (0, 2)(12, 10) 兩點間的距離:

(function () {

'use strict';

function squareRoot(n) {

if (n < 0)

throw new Error('Cannot take square root of negative number.');

return Math.sqrt(n);

}

function square(n) {

return n * n;

}

function pointDistance(pt1, pt2) {

return squareRoot((pt1.x - pt2.x) + (pt1.y - pt2.y));

}

function sample() {

var pt1 = { x: 0, y: 2 };

var pt2 = { x: 12, y: 10 };

console.log('Distance is: ' + pointDistance(pt1, pt2));

}

try {

sample();

}

catch (e) {

console.log(e.stack);

}

})();

該指令碼中包含一個缺陷,其未調整組件間的差異。因此,對於某些輸入而言,pointDistance 函數將返回錯誤的結果;而在其他情況中,該指令碼將導致錯誤發生。為了理解堆疊追蹤的含義,讓我們一同來查看 F12 開發人員工具中的錯誤,並查看其指令碼選項卡:

堆疊追蹤將轉儲至 catch 子句中的控制台,由於其位於堆棧的頂部,因此起源於 squareRoot 函數的錯誤將變得顯而易見。為了調試這一問題,開發人員無需深入查看堆疊追蹤;系統已違反 squareRoot 的前置條件,而且只需查看堆棧的上一級,原因將變得十分明了:squareRoot 調用內的子運算式自身應該為 square 的參數。

調試過程中,stack 屬性將有助於識別用於設定斷點的代碼。請記住:您還可使用其它方法來查看呼叫堆疊:例如,如果您將指令碼偵錯工具設定為“捕獲異常即中斷”的模式,那麼您可使用該偵錯工具來檢查呼叫堆疊。對於部署的應用程式,您可考慮在 try/catch 內合并問題代碼,以捕獲失敗的調用,並將其記錄於伺服器中。隨後,開發人員可查看呼叫堆疊,以隔離問題地區。

DOM 異常與 Error.stack

此前,我曾注意到被引發的對象必須為 Error 或通過其原型鏈導致 Error。這是有意而為之;JavaScript 可支援引發任何對象,甚至包括作為異常的基元。儘管系統可捕獲和檢查所有這些對象,但是它們的全部用途並非包含錯誤或診斷資訊。因此,引發過程中僅將更新錯誤的 stack 屬性。

即便對象為 DOM 異常,它們也不包含可導致 Error 的原型鏈,因此它們將不包含 stack 屬性。在某些應用情境中,您需要執行 DOM 操作,並希望暴露 JavaScript 相容的錯誤,那麼您可能希望在 try/catch 資料區塊內合并您的 DOM 作業碼,並在 catch 子句中引發一個新的 Error 對象:

function causesDomError() {

try {

var div = document.createElement('div');

div.appendChild(div);

} catch (e) {

throw new Error(e.toString());

}

}

然而,您可能將考慮是否要使用該模式。這可能是最適用於工具 + 生產力庫開發的模式,特別是在您考慮代碼的意圖是否為隱藏 DOM 操作或簡單地實施某一任務的時候。如果其目的為隱藏 DOM 操作,那麼合併作業並引發 Error 可能是我們需要選擇的正確方式。

效能注意事項

堆疊追蹤的構造始於錯誤對象被引發之時;構造堆疊追蹤需要查看當前執行堆棧。為了防止遍曆特大堆棧過程中出現效能問題(甚至可能出現的遞迴堆棧鏈),預設情況下,IE 僅將收集前十位的堆疊框架。然而該設定可通過將靜態屬性 Error.stackTraceLimit 設定為另一數值而得以配置。該設定是全域性的,而且必須在引發錯誤之前 進行變更,否則其將對堆疊追蹤無效。

非同步異常

當某一堆棧是由非同步回調(例如 timeoutintervalXMLHttpRequest)產生,那麼非同步回調(而非由非同步回調建立的代碼)將位於呼叫堆疊的底部。這將對跟蹤有問題的代碼產生某些潛在影響:如果您對多個非同步回調使用相同的回呼函數,那麼您將難於通過單獨檢查而確定是哪一回調產生了錯誤。讓我們對此前的樣本稍作修改,我們將避免直接調用 sample(),而是將其放入逾時回調:

(function () {

'use strict';

function squareRoot(n) {

if (n < 0)

throw new Error('Cannot take square root of negative number.');

return Math.sqrt(n);

}

function square(n) {

return n * n;

}

function pointDistance(pt1, pt2) {

return squareRoot((pt1.x - pt2.x) + (pt1.y - pt2.y));

}

function sample() {

var pt1 = { x: 0, y: 2 };

var pt2 = { x: 12, y: 10 };

console.log('Distance is: ' + pointDistance(pt1, pt2));

}

setTimeout(function () {

try {

sample();

}

catch (e) {

console.log(e.stack);

}

}, 2500);

})();

一旦執行該程式碼片段,您將發現堆疊追蹤將出現稍許延遲。此時,您將同時發現堆棧底部並非全域性代碼,而是Anonymous function。事實上,這並非同一匿名函數,而是傳遞至 setTimeout 的回呼函數。由於您丟失了與掛起回調有關的上下文,因此您可能無法確定調用回調的內容。如果在某一應用情境中,系統註冊了某一回調來處理許多不同按鈕的 click 事件,那麼您將無法分辨註冊將引用哪一回調。話雖如此,這一限制作用畢竟有限,因為在大多數情況中,堆棧頂部可能將反白問題地區。

觀看體驗示範

立即觀看本體驗示範,瞭解 Windows 8 Consumer Preview 中 IE10 的使用方式。您可在 eval 的上下文中執行代碼,如果發生錯誤,您便可檢查出該錯誤。如果您在 IE10 內運行代碼,由於您可將錯誤碼行懸停於堆疊追蹤中,因此您也可反白您的程式碼。您可自行將代碼輸入到代碼地區,或者從列表中的數個樣本中進行選擇。此外,您還可在運行程式碼範例時設定 Error.stackTraceLimit 值。

如欲查看參考材料,請瀏覽有關 Error.stackstackTraceLimit 的 MSDN 文檔。

部分轉載 IEBlog

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.