Настраиваемые трассировки стека в инструментах разработчика Google Chrome? - PullRequest
3 голосов
/ 28 мая 2011

Я хочу настроить элементы, отображаемые на панели трассировки треков на вкладке Сценарии инструментов разработчика Google Chrome.В частности, я хочу отфильтровать элементы в трассировке стека и добавить более описательные имена для некоторых элементов в трассировке стека без необходимости переименовывать мои объекты и функции.

Я нашел API трассировки стека V8 в http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi но переопределение Error.prepareStackTrace, похоже, не имеет никакого эффекта.

Ответы [ 3 ]

7 голосов
/ 08 июня 2012

Описание на этой странице определенно немного сложное, вот как это делается:

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 (параметр «стек» выше), так что это означает, что при попытке ... отловить ошибку Error.stack будет содержать массив CallSite объекты вместо обычной трассировки стека в виде строки. Другой подход заключается в обработке объектов CallSite внутри замещающей функции prepareStackTrace () и возвращении альтернативной трассировки стека в виде строки.

Обратите внимание, что объекты CallSite действительно привередливы. Попробуйте сделать frame.toString (), или просто попытаться предупредить (frame) (неявно это включает toString ()), и он вылетает, и инструменты разработчика Chrome не показывают ошибки.

1 голос
/ 28 января 2012

Вот код, который помог мне:

<head>
<script>
Error.prepareStackTrace = function()
{
        return "MyStackObject";
}
try {
  throw new Error();
} catch (e) {
  console.log(e.stack);
}
</script>
</head>
0 голосов
/ 04 октября 2016

Документация перенесена сюда: 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); }
...