2011-05-28 58 views
1

我正在尋找定製Google Chrome開發人員工具的腳本標籤中的strack trace面板中顯示的項目。具體來說,我想過濾掉堆棧跟蹤中的項目,併爲堆棧跟蹤中的某些項目添加更多描述性名稱,而無需重命名我的對象和函數。Google Chrome開發人員工具中的自定義堆棧跟蹤?

我發現V8的堆棧跟蹤API在http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi但重寫Error.prepareStackTrace似乎沒有任何效果。

+0

你如何覆蓋它,並在哪裏?你以後重啓Chrome嗎?你如何測試你的改變?你有沒有在鉻定製的其他領域有運氣? – gaRex 2011-05-28 19:13:46

回答

6

該網頁上的描述肯定是有點難以遵循,這裏是它是如何做:

Error.prepareStackTrace = function(error, stack) { 
    return stack; 
}; 

var someObj = { 
    someMethod : function() { 
     crash(); 
    } 
} 
function bar(barArg) { someObj.someMethod(); }; 
function foo(fooArg) { bar("barArgString"); }; 

function getTrace(e) { 
    var stack = e.stack; 
    var trace = ""; 

    for (var i = 0; i < stack.length; i++) { 
     var frame = stack[i], 
      func = frame.getFunction(); 

     trace += "\r" + frame.getThis() + "." + frame.getFunctionName(); 
    } 
    return trace; 
} 

try { 
    foo("fooArgString"); 
} catch (e) { 
    alert("trace from catch(): " + getTrace(e)); 
} 

這將顯示:

trace from catch(): 
[object Object].someObj.someMethod 
[object Window].bar 
[object Window].foo 
[object Window]. 

最後一幀是全局作用域(無函數名)。

基本上,您對prepareStackTrace()的重寫會導致error.stack成爲您從prepareStackTrace()返回的任何內容。訣竅是prepareStackTrace()的第二個參數是一個CallSite對象數組 - 支持getThis(),getFunctionName()等的對象。

上面的代碼覆蓋prepareStackTrace(),以便它返回CallSite數組對象(上面的「stack」參數),所以這意味着當你嘗試......捕獲一個錯誤時,Error.stack將包含CallSite對象數組,而不是通常的字符串形式的堆棧跟蹤。另一種方法是在替換prepareStackTrace()函數內處理CallSite對象,並將替代堆棧跟蹤作爲字符串返回。

請注意CallSite對象真的很挑剔。嘗試做frame.toString(),或者試圖提醒(框架)(隱含地這涉及toString()),它崩潰,Chrome的開發人員工具顯示沒有錯誤。

1

下面是奏效了,我的代碼:

<head> 
<script> 
Error.prepareStackTrace = function() 
{ 
     return "MyStackObject"; 
} 
try { 
    throw new Error(); 
} catch (e) { 
    console.log(e.stack); 
} 
</script> 
</head> 
0

的文檔已移至此處: https://github.com/v8/v8/wiki/Stack-Trace-API

只是把這個在你的JavaScript代碼開始,它格式化一個不錯的堆棧跟蹤:

Error.prepareStackTrace = function(error, stack) { 
    var trace = ''; 
    var max_width = 0; 
    for (var i = 0; i < stack.length; i++){ 
     var frame = stack[i]; 

     var typeLength = 0; 
     typeLength = (frame.getTypeName() !== null && frame.getTypeName() !== '[object global]') ? frame.getTypeName().length : 0; 
     typeLength = typeLength.length > 50 ? 50 : typeLength; 

     functionlength = frame.getFunctionName() !== null ? frame.getFunctionName().length : '<anonymous>'.length; 
     functionlength = functionlength > 50 ? 50 : functionlength; 

     if (typeLength + functionlength > max_width) 
      max_width = typeLength + functionlength; 
    } 

    for (var i = 0; i < stack.length; i++) { 
     var frame = stack[i]; 

     var filepath = frame.getFileName(); 

     var typeName = ''; 
     if (frame.getTypeName() !== null && frame.getTypeName() !== '[object global]') 
      typeName = frame.getTypeName().substring(0, 50) + '.'; 

     var functionName = '<anonymous>'; 
     if (frame.getFunctionName() !== null) 
      functionName = frame.getFunctionName().substring(0, 50); 

     var space = ''; 
     var width = max_width - (typeName.length + functionName.length) + 2; 
     space = Array(width).join(' '); 
     var line = ' at ' + typeName + functionName + space + filepath + 
      ' (' + frame.getLineNumber() + 
      ':' + frame.getColumnNumber() + ')\n'; 

     trace += line; 
    } 
    return trace; 
}; 

下面是一個例子來測試的代碼:

function A() { B(); } 
function B() { C(); } 
function C() { throw new Error('asd'); } 
try { 
    A(); 
} catch (e) { print(e + '\n' + e.stack); } 
相關問題