2011-05-28 134 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); } 
相关问题