简体   繁体   English

Google Chrome 开发人员工具中的自定义堆栈跟踪?

[英]Customized Stack Traces in Google Chrome Developer Tools?

I'm looking to customize the items that show up in the strack trace panel in the Scripts tab of Google Chrome's developers tools.我正在寻找自定义显示在 Google Chrome 开发人员工具的“脚本”选项卡中的 strack 跟踪面板中的项目。 Specifically, I want to filter out items in the stack trace and to add more descriptive names to some of the items on the stack trace without having to rename my objects and functions.具体来说,我想过滤掉堆栈跟踪中的项目,并为堆栈跟踪中的某些项目添加更具描述性的名称,而不必重命名我的对象和函数。

I found V8's Stack Trace API at http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi but overriding Error.prepareStackTrace doesn't seem to have any effect.我在http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi找到了 V8 的堆栈跟踪 API,但覆盖 Error.prepareStackTrace 似乎没有任何效果。

The description on that page is definitely a little hard to follow, here's how it's done:该页面上的描述肯定有点难以理解,这是它的完成方式:

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));
}

This will show:这将显示:

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

The last frame is global scope (no function name).最后一帧是全局 scope(没有 function 名称)。

Essentially your override of prepareStackTrace() causes error.stack to become whatever you return from prepareStackTrace().本质上,您对 prepareStackTrace() 的覆盖会导致 error.stack 成为您从 prepareStackTrace() 返回的任何内容。 The trick is that the second argument to prepareStackTrace() is an Array of CallSite objects - the objects that support getThis(), getFunctionName() etc.诀窍是 prepareStackTrace() 的第二个参数是一个 CallSite 对象数组 - 支持 getThis()、getFunctionName() 等的对象。

The code above overrides prepareStackTrace() so that it returns the Array of CallSite objects ("stack" parameter above), so this means when you try..catch an Error, Error.stack is going to contain the Array of CallSite objects instead of the usual stack trace in String form.上面的代码覆盖了 prepareStackTrace() 以便它返回 CallSite 对象数组(上面的“stack”参数),因此这意味着当您尝试..catch 错误时,Error.stack 将包含 CallSite 对象数组而不是字符串形式的常用堆栈跟踪。 Another approach would be to process the CallSite objects inside of your replacement prepareStackTrace() function and return your alternative stack trace as a String.另一种方法是处理替换 prepareStackTrace() function 中的 CallSite 对象,并将替代堆栈跟踪作为字符串返回。

Note the CallSite objects are really finicky.请注意,CallSite 对象非常挑剔。 Try to do frame.toString(), or just try to alert(frame) (implicitly this involves toString()) and it crashes and Chrome's developer tools show no error.尝试执行 frame.toString(),或者只是尝试 alert(frame)(隐含这涉及 toString())并且它崩溃并且 Chrome 的开发工具显示没有错误。

Here's the code that did the trick for me:这是对我有用的代码:

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

The documentation has moved here: https://github.com/v8/v8/wiki/Stack-Trace-API文档已移至此处: https://github.com/v8/v8/wiki/Stack-Trace-API

Just put this at the beginning of your javascript code, it formats a nice stack trace:只需将它放在 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;
};

Here's an example to the test the code:这是测试代码的示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM