Как я могу получить трассировку стека JavaScript при выдаче исключения?

519

Если я сам создаю исключение JavaScript (например, throw "AArrggg"), как я могу получить трассировку стека (в Firebug или иначе)? Прямо сейчас я просто получаю сообщение.

редактировать : как много людей ниже опубликовали, возможно получить трассировку стека для исключения JavaScript, но я хочу получить трассировку стека для моих исключений. Например:

function foo() {
    bar(2);
}
function bar(n) {
    if (n < 2)
        throw "Oh no! 'n' is too small!"
    bar(n-1);
}

Когда fooназывается, я хочу , чтобы получить трассировку стека , который включает в себя вызовы foo, bar, bar.

Дэвид Волевер
источник
1
возможный дубликат трассировки стека исключений Javascript
ripper234
Ошибка по-прежнему открыта на трекере ошибок Firebug с 2008 года: code.google.com/p/fbug/issues/detail?id=1260 - отметьте это!
Миллер Медейрос
13
Ответ должен быть "выбросить новую ошибку ('arrrgh');" см. эту хорошо написанную страницу: devthought.com/2011/12/22/a-string-is-not-an-error
элегантные кости
1
(2013) Теперь вы можете получать трассировки стека в Firebug на Firefox, даже если это просто throw 'arrrgh';, и они выглядят так же, как и с throw new Error('arrrgh');. Отладчик Chrome все еще нуждается throw new Error('arrrgh');в том, что заявлено, однако (но Chrome, кажется, дает намного более детальные следы).
user56reinstatemonica8
26
@ChetanSastry Я погуглил «трассировку стека javascript», и это был первый результат
Дэвид Сайкс

Ответы:

756

Изменить 2 (2017):

Во всех современных браузерах вы можете просто позвонить: console.trace(); (MDN Reference)

Изменить 1 (2013):

Лучшее (и более простое) решение, как указано в комментариях к исходному вопросу, заключается в использовании stackсвойства Errorобъекта следующим образом:

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Это сгенерирует вывод так:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Предоставление имени вызывающей функции вместе с URL, вызывающей функцией и т. Д.

Оригинал (2009):

Модифицированная версия этого фрагмента может несколько помочь:

function stacktrace() { 
  function st2(f) {
    return !f ? [] : 
        st2(f.caller).concat([f.toString().split('(')[0].substring(9) + '(' + f.arguments.join(',') + ')']);
  }
  return st2(arguments.callee.caller);
}
Евгений Морозов
источник
11
Я не уверен, почему за это больше не голосуют - другие ответы не сработали для меня. Кстати, убедитесь, что аргументы не рассматриваются как массив (обновленный фрагмент здесь: gist.github.com/965603 )
ripper234
1
не работает в chrome, tacktrace (): [Exception: TypeError: Object # <Object> не имеет метода
hetaoblog
3
см. комментарий к исходному вопросу: вам не нужен пользовательский код, просто используйте «throw new Error ('arrrgh')»
Джошуа Ричардсон,
16
Error.stack не определен в IE, работает только в Chrome и Mozilla Firefox
Филипп Мунин
4
Обратите внимание, что callerтеперь устарела и calleeудалена из строгого режима ES5. Вот почему stackoverflow.com/questions/103598/…
PhilT
187

Обратите внимание, что chromium / chrome (другие браузеры, использующие V8), а также Firefox имеют удобный интерфейс для получения трассировки стека через свойство стека объектов Error .

try {
   // Code throwing an exception
} catch(e) {
  console.log(e.stack);
}

Это относится как к базовым исключениям, так и к тем, которые вы бросаете сами. (Считается, что вы используете класс Error, который в любом случае является хорошей практикой).

Подробности смотрите в документации V8

Джоселин Делаланде
источник
12
Firefox также поддерживает это .stackсвойство.
Kennytm
2
Хотелось бы, чтобы я проголосовал 100 раз! Спасибо Джоселин. Это очень помогло
сафразик
1
Вы также можете использовать console.error(e.stack);его так, чтобы оно выглядело как сообщение об исключении по умолчанию
Bruno Peres
80

В Firefox кажется, что вам не нужно бросать исключение. Достаточно сделать

e = new Error();
console.log(e.stack);
Джастин Л.
источник
Работает и в мобильных приложениях (созданных с использованием JQM).
Самик Р
Работает и в Chromium (версия 43 в любом случае).
Энди Беверли
В Firefox 59 это не работает при вызове через window.onerror, он показывает почти пустой стек только с onerrorфункцией.
Code4R7
Еще лучше, вы могли бы сделать: console.log(new Error().stack)> :(> :(> :(
Андрей
25

Если у вас есть firebug, на вкладке скрипта есть опция break on all errors. Как только сценарий достигнет вашей точки останова, вы можете посмотреть в окне стека firebug:

Скриншот

Helephant
источник
5
Хм, это не похоже на работу. Это останавливает меня в отладчике ошибок, возникающих в Javascript (например, неопределенные переменные ошибки), но когда я выкидываю свои собственные исключения, я все равно не получаю ничего, кроме сообщения «Uncaught exception».
Дэвид Воловер
11

Хорошее (и простое) решение, как указано в комментариях к исходному вопросу, заключается в использовании stackсвойства Errorобъекта следующим образом:

function stackTrace() {
    var err = new Error();
    return err.stack;
}

Это сгенерирует вывод так:

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

Предоставление имени вызывающей функции вместе с URL и номером строки, ее вызывающей функцией и т. Д.

У меня есть действительно продуманное и красивое решение, которое я разработал для проекта, над которым я сейчас работаю, и я его немного извлек и переработал, чтобы обобщить. Вот:

(function(context){
    // Only global namespace.
    var Console = {
        //Settings
        settings: {
            debug: {
                alwaysShowURL: false,
                enabled: true,
                showInfo: true
            },
            stackTrace: {
                enabled: true,
                collapsed: true,
                ignoreDebugFuncs: true,
                spacing: false
            }
        }
    };

    // String formatting prototype function.
    if (!String.prototype.format) {
        String.prototype.format = function () {
            var s = this.toString(),
                args = typeof arguments[0],
                args = (("string" == args || "number" == args) ? arguments : arguments[0]);
            if (!arguments.length)
                return s;
            for (arg in args)
                s = s.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
            return s;
        }
    }

    // String repeating prototype function.
    if (!String.prototype.times) {
        String.prototype.times = function () {
            var s = this.toString(),
                tempStr = "",
                times = arguments[0];
            if (!arguments.length)
                return s;
            for (var i = 0; i < times; i++)
                tempStr += s;
            return tempStr;
        }
    }

    // Commonly used functions
    Console.debug = function () {
        if (Console.settings.debug.enabled) {
            var args = ((typeof arguments !== 'undefined') ? Array.prototype.slice.call(arguments, 0) : []),
                sUA = navigator.userAgent,
                currentBrowser = {
                    firefox: /firefox/gi.test(sUA),
                    webkit: /webkit/gi.test(sUA),
                },
                aLines = Console.stackTrace().split("\n"),
                aCurrentLine,
                iCurrIndex = ((currentBrowser.webkit) ? 3 : 2),
                sCssBlack = "color:black;",
                sCssFormat = "color:{0}; font-weight:bold;",
                sLines = "";

            if (currentBrowser.firefox)
                aCurrentLine = aLines[iCurrIndex].replace(/(.*):/, "$1@").split("@");
            else if (currentBrowser.webkit)
                aCurrentLine = aLines[iCurrIndex].replace("at ", "").replace(")", "").replace(/( \()/gi, "@").replace(/(.*):(\d*):(\d*)/, "$1@$2@$3").split("@");

            // Show info if the setting is true and there's no extra trace (would be kind of pointless).
            if (Console.settings.debug.showInfo && !Console.settings.stackTrace.enabled) {
                var sFunc = aCurrentLine[0].trim(),
                    sURL = aCurrentLine[1].trim(),
                    sURL = ((!Console.settings.debug.alwaysShowURL && context.location.href == sURL) ? "this page" : sURL),
                    sLine = aCurrentLine[2].trim(),
                    sCol;

                if (currentBrowser.webkit)
                    sCol = aCurrentLine[3].trim();

                console.info("%cOn line %c{0}%c{1}%c{2}%c of %c{3}%c inside the %c{4}%c function:".format(sLine, ((currentBrowser.webkit) ? ", column " : ""), ((currentBrowser.webkit) ? sCol : ""), sURL, sFunc),
                             sCssBlack, sCssFormat.format("red"),
                             sCssBlack, sCssFormat.format("purple"),
                             sCssBlack, sCssFormat.format("green"),
                             sCssBlack, sCssFormat.format("blue"),
                             sCssBlack);
            }

            // If the setting permits, get rid of the two obvious debug functions (Console.debug and Console.stackTrace).
            if (Console.settings.stackTrace.ignoreDebugFuncs) {
                // In WebKit (Chrome at least), there's an extra line at the top that says "Error" so adjust for this.
                if (currentBrowser.webkit)
                    aLines.shift();
                aLines.shift();
                aLines.shift();
            }

            sLines = aLines.join(((Console.settings.stackTrace.spacing) ? "\n\n" : "\n")).trim();

            trace = typeof trace !== 'undefined' ? trace : true;
            if (typeof console !== "undefined") {
                for (var arg in args)
                    console.debug(args[arg]);

                if (Console.settings.stackTrace.enabled) {
                    var sCss = "color:red; font-weight: bold;",
                        sTitle = "%c Stack Trace" + " ".times(70);

                    if (Console.settings.stackTrace.collapsed)
                        console.groupCollapsed(sTitle, sCss);
                    else
                        console.group(sTitle, sCss);

                    console.debug("%c" + sLines, "color: #666666; font-style: italic;");

                    console.groupEnd();
                }
            }
        }
    }
    Console.stackTrace = function () {
        var err = new Error();
        return err.stack;
    }

    context.Console = Console;
})(window);

Проверьте это на GitHub (в настоящее время v1.2)! Вы можете использовать его как, Console.debug("Whatever");и он, в зависимости от настроек Console, напечатает вывод и трассировку стека (или просто простую информацию / ничего лишнего вообще). Вот пример:

Console.js

Обязательно поиграйтесь с настройками Consoleобъекта! Вы можете добавить интервал между линиями трассировки и полностью отключить его. Вот оно с Console.traceустановленным на false:

Никаких следов

Вы даже можете отключить первый бит отображаемой информации (установить Console.settings.debug.showInfoв false) или полностью отключить отладку (установить Console.settings.debug.enabledв false), чтобы вам больше никогда не приходилось комментировать оператор отладки! Просто оставьте их, и это ничего не сделает.

Габриэль Намиас
источник
10

Я не думаю, что есть что-то встроенное, что вы можете использовать, но я нашел много примеров, когда люди катались самостоятельно.

Марк Бик
источник
Ах, спасибо - первая ссылка там может показаться полезной (хотя отсутствие поддержки рекурсии может сделать ее неработоспособной).
Дэвид Волевер
Да, я не видел ни одной, которая поддерживала бы рекурсию на первый взгляд. Мне будет любопытно посмотреть, есть ли хорошее решение для этого.
Марк Бик
1
Я думаю, что вторая ссылка должна поддерживать рекурсию для Firefox и Opera, потому что она использует трассировку стека ошибок, а не создает ее вручную, используя переменную arguments. Я хотел бы услышать, если вы найдете кросс-браузерное решение для проблемы рекурсии (первая статья моя). :)
Helephant
Helephant: второе здесь не сработает, потому что, когда я ловлю исключение, это "строка" (т. Е. Нет "e.stack"): foo = function () {throw "Arg"; } try {foo (); } catch (e) {/ * typeof e == "string" * /} Может я ошибаюсь? (начните обязательную напыщенную речь о том, насколько глупы уроки по Javascript ...)
Дэвид Волевер
Попробуйте бросить объект throw { name: 'NameOfException', message: 'He's dead, Jim' }.
Аарон Дигулла
7

Вы можете получить доступ к stack( stacktraceв Opera) свойств Errorэкземпляра, даже если вы бросили его. Дело в том, что вы должны убедиться, что вы используете throw new Error(string)(не забудьте новое вместо throw string.

Пример:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}
Эли Грей
источник
stacktrace не работает в Opera. Я даже не могу найти что-то об этом.
NVI
@NV: кажется, что stacktrace не относится к ошибкам, созданным пользователем, поэтому вы должны сделать это вместо этого: try {0 ++} catch (e) {myStackTrace = e.stack || e.stacktrace}
Эли Грей,
7

Это даст трассировку стека (в виде массива строк) для современных Chrome, Opera, Firefox и IE10 +.

function getStackTrace () {

  var stack;

  try {
    throw new Error('');
  }
  catch (error) {
    stack = error.stack || '';
  }

  stack = stack.split('\n').map(function (line) { return line.trim(); });
  return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

Применение:

console.log(getStackTrace().join('\n'));

Он исключает из стека свой собственный вызов, а также заголовок «Ошибка», который используется Chrome и Firefox (но не IE).

Он не должен падать в старых браузерах, а просто возвращать пустой массив. Если вам нужно более универсальное решение, посмотрите на stacktrace.js . Его список поддерживаемых браузеров действительно впечатляет, но, на мой взгляд, он очень большой для той небольшой задачи, для которой он предназначен: 37 КБ минимизированного текста, включая все зависимости.

Константин Смолянин
источник
7

Обновление к ответу Юджина: объект ошибки должен быть брошен для IE (определенные версии?), Чтобы заполнить stackсвойство. Следующее должно работать лучше, чем его текущий пример, и должно избегать возврата undefinedв IE.

function stackTrace() {
  try {
    var err = new Error();
    throw err;
  } catch (err) {
    return err.stack;
  }
}

Примечание 1: Подобные действия следует выполнять только при отладке и отключать при работе, особенно если они часто вызываются. Примечание 2: Это может работать не во всех браузерах, но, похоже, работает в FF и IE 11, что вполне соответствует моим потребностям.

Патрик Сеймур
источник
6

Один из способов получить реальную трассировку стека в Firebug - создать реальную ошибку, такую ​​как вызов неопределенной функции:

function foo(b){
  if (typeof b !== 'string'){
    // undefined Error type to get the call stack
    throw new ChuckNorrisError("Chuck Norris catches you.");
  }
}

function bar(a){
  foo(a);
}

foo(123);

Или используйте с console.error()последующим throwоператором, поскольку console.error()показывает трассировку стека.

Миллер Медейрос
источник
4

Этот полифилл-код работает в современных (2017) браузерах (IE11, Opera, Chrome, FireFox, Yandex):

printStackTrace: function () {
    var err = new Error();
    var stack = err.stack || /*old opera*/ err.stacktrace || ( /*IE11*/ console.trace ? console.trace() : "no stack info");
    return stack;
}

Другие ответы:

function stackTrace() {
  var err = new Error();
  return err.stack;
}

не работает в IE 11!

Использование arguments.callee.caller - не работает в строгом режиме ни в одном браузере!

Петр Варягин
источник
3

В Google Chrome (версия 19.0 и выше) простое создание исключения работает отлично. Например:

/* file: code.js, line numbers shown */

188: function fa() {
189:    console.log('executing fa...');
190:    fb();
191: }
192:
193: function fb() {
194:    console.log('executing fb...');
195:    fc()
196: }
197:
198: function fc() {
199:    console.log('executing fc...');
200:    throw 'error in fc...'
201: }
202:
203: fa();

покажет трассировку стека на выходе браузера:

executing fa...                         code.js:189
executing fb...                         code.js:194
executing fc...                         cdoe.js:199
/* this is your stack trace */
Uncaught error in fc...                 code.js:200
    fc                                  code.js:200
    fb                                  code.js:195
    fa                                  code.js:190
    (anonymous function)                code.js:203

Надеюсь, это поможет.

Рабих Кодейх
источник
3

функция:

function print_call_stack(err) {
    var stack = err.stack;
    console.error(stack);
}

вариант использования:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
Jaskey
источник
2
<script type="text/javascript"
src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>

этот скрипт покажет ошибку

Амир Бузо
источник
2
function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}
Денис Орлов
источник
2
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа.
Дональд Дак
1

В некотором роде поздно, но вот еще одно решение, которое автоматически определяет, если arguments.callee доступен, и использует новый Error (). Stack, если нет. Испытано в Chrome, Safari и Firefox.

2 варианта - stackFN (n) дает вам имя функции n вдали от непосредственного вызывающего, а stackArray () дает вам массив, stackArray () [0] является непосредственным вызывающим.

Попробуйте это на http://jsfiddle.net/qcP9y/6/

// returns the name of the function at caller-N
// stackFN()  = the immediate caller to stackFN
// stackFN(0) = the immediate caller to stackFN
// stackFN(1) = the caller to stackFN's caller
// stackFN(2) = and so on
// eg console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
function stackFN(n) {
    var r = n ? n : 0, f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (r-- >= 0) {
            tl(")");
        }
        tl(" at ");
        tr("(");
        return s;
    } else {
        if (!avail) return null;
        s = "f = arguments.callee"
        while (r>=0) {
            s+=".caller";
            r--;   
        }
        eval(s);
        return f.toString().split("(")[0].trim().split(" ")[1];
    }
}
// same as stackFN() but returns an array so you can work iterate or whatever.
function stackArray() {
    var res=[],f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (s.indexOf(")")>=0) {
            tl(")");
            s2= ""+s;
            tl(" at ");
            tr("(");
            res.push(s);
            s=""+s2;
        }
    } else {
        if (!avail) return null;
        s = "f = arguments.callee.caller"
        eval(s);
        while (f) {
            res.push(f.toString().split("(")[0].trim().split(" ")[1]);
            s+=".caller";
            eval(s);
        }
    }
    return res;
}


function apple_makes_stuff() {
    var retval = "iPhones";
    var stk = stackArray();

    console.log("function ",stk[0]+"() was called by",stk[1]+"()");
    console.log(stk);
    console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
    return retval;
}



function apple_makes (){
    return apple_makes_stuff("really nice stuff");
}

function apple () {
    return apple_makes();
}

   apple();
синхронизирован
источник
1

Вы можете использовать эту библиотеку http://www.stacktracejs.com/ . Это очень хорошо

Из документации

Вы также можете передать свою собственную ошибку, чтобы получить трассировку стека, недоступную в IE или Safari 5-

<script type="text/javascript" src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>
Доу Бери
источник
Связанный источник https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js- старая версия, самая последняя стабильная версия (соответствует фрагменту кода) здесь:https://raw.githubusercontent.com/stacktracejs/stacktrace.js/stable/stacktrace.js
Фредерик Лейтенбергер,
1

Вот ответ, который дает вам максимальную производительность (IE 6+) и максимальную совместимость. Совместим с IE 6!

    function stacktrace( log_result ) {
    	var trace_result;
    // IE 6 through 9 compatibility
    // this is NOT an all-around solution because
    // the callee property of arguments is depredicated
    /*@cc_on
    	// theese fancy conditinals make this code only run in IE
    	trace_result = (function st2(fTmp) {
    		// credit to Eugene for this part of the code
    		return !fTmp ? [] :
    			st2(fTmp.caller).concat([fTmp.toString().split('(')[0].substring(9) + '(' + fTmp.arguments.join(',') + ')']);
    	})(arguments.callee.caller);
    	if (log_result) // the ancient way to log to the console
    		Debug.write( trace_result );
    	return trace_result;
    @*/
    	console = console || Console;	// just in case
    	if (!(console && console.trace) || !log_result){
    		// for better performance in IE 10
    		var STerror=new Error();
    		var unformated=(STerror.stack || STerror.stacktrace);
    		trace_result = "\u25BC console.trace" + unformated.substring(unformated.indexOf('\n',unformated.indexOf('\n'))); 
    	} else {
    		// IE 11+ and everyone else compatibility
    		trace_result = console.trace();
    	}
    	if (log_result)
    		console.log( trace_result );
    	
    	return trace_result;
    }
// test code
(function testfunc(){
	document.write( "<pre>" + stacktrace( false ) + "</pre>" );
})();

Джек Гиффин
источник
0

Легче получить трассировку стека в Firefox, чем в IE, но в основном вот что вы хотите сделать:

Оберните «проблемный» фрагмент кода в блок try / catch:

try {
    // some code that doesn't work
    var t = null;
    var n = t.not_a_value;
}
    catch(e) {
}

Если вы изучите содержимое объекта «error», он содержит следующие поля:

e.fileName: исходный файл / страница, с которой возникла проблема. e.lineNumber: номер строки в файле / странице, на которой возникла проблема. e.message: простое сообщение с описанием типа ошибки. e.name: тип ошибки, которая произошла, в приведенном выше примере это должно быть 'TypeError' e.stack: содержит трассировку стека, вызвавшую исключение

Я надеюсь, что это помогает вам.

Майкл
источник
1
Неправильно. Он пытается поймать свои СОБСТВЕННЫЕ исключения. Если он бросит «asdfg», он получит строковый объект, а не объект исключения. Он не пытается поймать встроенные исключения.
Иван Вучица,
0

Мне пришлось исследовать бесконечную рекурсию в smartgwt с IE11, поэтому для более глубокого исследования мне потребовалась трассировка стека. Проблема заключалась в том, что я не мог использовать консоль разработчика, потому что воспроизведение было сложнее.
Используйте следующее в методе javascript:

try{ null.toString(); } catch(e) { alert(e.stack); }
kirilv
источник
alert ((новая ошибка ()). stack);
богатый ремер
0

Ничего себе - я не вижу ни одного человека за 6 лет, который предложил бы сначала проверить, есть ли stackв наличии, прежде чем его использовать! Худшее, что вы можете сделать в обработчике ошибок, это выдать ошибку из-за вызова чего-то, что не существует.

Как уже говорили другие, в то время stackкак в большинстве случаев безопаснее использовать, он не поддерживается в IE9 или более ранних версиях.

Я регистрирую свои неожиданные ошибки, и трассировка стека довольно важна. Для максимальной поддержки я сначала проверяю, Error.prototype.stackсуществует ли она и является ли она функцией. Если это так, то это безопасно для использования error.stack.

        window.onerror = function (message: string, filename?: string, line?: number, 
                                   col?: number, error?: Error)
        {
            // always wrap error handling in a try catch
            try 
            {
                // get the stack trace, and if not supported make our own the best we can
                var msg = (typeof Error.prototype.stack == 'function') ? error.stack : 
                          "NO-STACK " + filename + ' ' + line + ':' + col + ' + message;

                // log errors here or whatever you're planning on doing
                alert(msg);
            }
            catch (err)
            {

            }
        };

Редактировать: Похоже, что поскольку stackэто свойство, а не метод, вы можете безопасно вызывать его даже в старых браузерах. Я все еще в замешательстве, потому что Error.prototypeраньше я был уверен, что проверка сработала для меня, а теперь - нет, поэтому я не уверен, что происходит.

Simon_Weaver
источник
0

Использование console.error(e.stack)Firefox показывает только трассировку стека в журналах, Chrome также показывает сообщение. Это может быть неприятным сюрпризом, если сообщение содержит важную информацию. Всегда регистрируйте оба.

Кристоф Русси
источник
0

Просто попробуй

throw new Error('some error here')

Это работает очень хорошо для Chrome:

введите описание изображения здесь

Энтони Жан
источник