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

#javascript #google-chrome #v8 #chromium

#javascript #google-chrome #версия 8 #chromium

Вопрос:

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

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

Комментарии:

1. как вы переопределяете это и где? Вы перезапускаете Chrome после? Как вы тестируете свои изменения? Были ли у вас успехи в других областях настройки Chrome?

Ответ №1:

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

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

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

Ответ №2:

Вот код, который сделал это за меня:

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

Ответ №3:

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