我正在尋找定製Google Chrome開發人員工具的腳本標籤中的strack trace面板中顯示的項目。具體來說,我想過濾掉堆棧跟蹤中的項目,併爲堆棧跟蹤中的某些項目添加更多描述性名稱,而無需重命名我的對象和函數。Google Chrome開發人員工具中的自定義堆棧跟蹤?
我發現V8的堆棧跟蹤API在http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi但重寫Error.prepareStackTrace似乎沒有任何效果。
我正在尋找定製Google Chrome開發人員工具的腳本標籤中的strack trace面板中顯示的項目。具體來說,我想過濾掉堆棧跟蹤中的項目,併爲堆棧跟蹤中的某些項目添加更多描述性名稱,而無需重命名我的對象和函數。Google Chrome開發人員工具中的自定義堆棧跟蹤?
我發現V8的堆棧跟蹤API在http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi但重寫Error.prepareStackTrace似乎沒有任何效果。
該網頁上的描述肯定是有點難以遵循,這裏是它是如何做:
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的開發人員工具顯示沒有錯誤。
下面是奏效了,我的代碼:
<head>
<script>
Error.prepareStackTrace = function()
{
return "MyStackObject";
}
try {
throw new Error();
} catch (e) {
console.log(e.stack);
}
</script>
</head>
的文檔已移至此處: 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); }
你如何覆蓋它,並在哪裏?你以後重啓Chrome嗎?你如何測試你的改變?你有沒有在鉻定製的其他領域有運氣? – gaRex 2011-05-28 19:13:46