簡體   English   中英

Google Chrome 開發人員工具中的自定義堆棧跟蹤?

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

我正在尋找自定義顯示在 Google Chrome 開發人員工具的“腳本”選項卡中的 strack 跟蹤面板中的項目。 具體來說,我想過濾掉堆棧跟蹤中的項目,並為堆棧跟蹤中的某些項目添加更具描述性的名稱,而不必重命名我的對象和函數。

我在http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi找到了 V8 的堆棧跟蹤 API,但覆蓋 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].

最后一幀是全局 scope(沒有 function 名稱)。

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

上面的代碼覆蓋了 prepareStackTrace() 以便它返回 CallSite 對象數組(上面的“stack”參數),因此這意味着當您嘗試..catch 錯誤時,Error.stack 將包含 CallSite 對象數組而不是字符串形式的常用堆棧跟蹤。 另一種方法是處理替換 prepareStackTrace() function 中的 CallSite 對象,並將替代堆棧跟蹤作為字符串返回。

請注意,CallSite 對象非常挑剔。 嘗試執行 frame.toString(),或者只是嘗試 alert(frame)(隱含這涉及 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); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM