【问题标题】:Customized Stack Traces in Google Chrome Developer Tools?Google Chrome 开发人员工具中的自定义堆栈跟踪?
【发布时间】:2011-09-04 01:30:24
【问题描述】:

我正在寻找自定义显示在 Google Chrome 开发人员工具的“脚本”选项卡中的 strack 跟踪面板中的项目。具体来说,我想过滤掉堆栈跟踪中的项目,并为堆栈跟踪中的某些项目添加更具描述性的名称,而无需重命名我的对象和函数。

我在http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi 找到了 V8 的 Stack Trace API,但覆盖 Error.prepareStackTrace 似乎没有任何效果。

【问题讨论】:

  • 如何覆盖它以及在哪里覆盖?你之后重启chrome吗?你如何测试你的改变?你在 chrome 定制的其他领域有什么运气吗?

标签: javascript google-chrome v8 chromium


【解决方案1】:

文档已移至此处: 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); }

【讨论】:

    【解决方案2】:

    该页面上的描述肯定有点难以理解,它是如何完成的:

    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”参数),所以这意味着当你 try..catch 一个错误时,Error.stack 将包含 CallSite 的数组对象而不是通常的字符串形式的堆栈跟踪。另一种方法是在您的替换 prepareStackTrace() 函数中处理 CallSite 对象,并将您的替代堆栈跟踪作为字符串返回。

    请注意,CallSite 对象非常挑剔。尝试执行 frame.toString(),或者只是尝试 alert(frame)(隐含这涉及 toString())并且它崩溃并且 Chrome 的开发工具显示没有错误。

    【讨论】:

      【解决方案3】:

      这是对我有用的代码:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-23
        • 2019-07-09
        • 1970-01-01
        • 1970-01-01
        • 2011-10-19
        • 2015-11-19
        • 1970-01-01
        • 2013-06-18
        相关资源
        最近更新 更多