Описание на этой странице определенно немного сложно понять, вот как это делается:
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