3

GoogleChromeの開発者ツールの[スクリプト]タブのスタックトレースパネルに表示されるアイテムをカスタマイズしたいと考えています。具体的には、オブジェクトや関数の名前を変更せずに、スタックトレース内のアイテムを除外し、スタックトレース上のいくつかのアイテムにわかりやすい名前を追加したいと考えています。

http://code.google.com/p/v8/wiki/JavaScriptStackTraceApiでV8のStackTraceAPIを見つけましたが、Error.prepareStackTraceをオーバーライドしても効果がないようです。

4

3 に答える 3

7

そのページの説明を理解するのは確かに少し難しいです、これがどのように行われるかです:

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()の2番目の引数がCallSiteオブジェクトの配列(getThis()、getFunctionName()などをサポートするオブジェクト)であるということです。

上記のコードはprepareStackTrace()をオーバーライドして、CallSiteオブジェクトの配列(上記の「stack」パラメーター)を返すようにします。つまり、エラーをキャッチしようとすると、Error.stackにはCallSiteオブジェクトの配列が含まれます。文字列形式の通常のスタックトレース。別のアプローチは、置換のprepareStackTrace()関数内でCallSiteオブジェクトを処理し、代替のスタックトレースを文字列として返すことです。

CallSiteオブジェクトは本当に気難しいことに注意してください。frame.toString()を実行するか、alert(frame)を実行してみてください(暗黙的にこれにはtoString()が含まれます)。クラッシュし、Chromeの開発ツールはエラーを表示しません。

于 2012-06-08T02:35:35.847 に答える
1

これが私のためにトリックをしたコードです:

<head>
<script>
Error.prepareStackTrace = function()
{
        return "MyStackObject";
}
try {
  throw new Error();
} catch (e) {
  console.log(e.stack);
}
</script>
</head>
于 2012-01-28T14:23:29.037 に答える
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); }
于 2016-10-04T13:47:38.710 に答える