Настраиваемые трассировки стека в инструментах разработчика Google Chrome?

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

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


person soso    schedule 28.05.2011    source источник
comment
как переопределить и где? Вы перезапускаете хром после? Как вы тестируете свои изменения? Удалось ли вам в других областях настройки Chrome?   -  person gaRex    schedule 28.05.2011


Ответы (3)


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

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 не показывают ошибок.

person Charles Kendrick    schedule 08.06.2012

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

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

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