如果我自己抛出一个JavaScript异常(例如,抛出“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的调用。


当前回答

哇——我在6年里没有看到一个人建议我们在使用堆栈之前先检查它是否可用!在错误处理程序中,最糟糕的事情就是因为调用了不存在的东西而抛出错误。

正如其他人所说,虽然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)
            {

            }
        };

编辑:似乎因为堆栈是一个属性而不是一个方法,你可以安全地调用它,即使在旧的浏览器。我仍然感到困惑,因为我非常确定检查错误。原型以前为我工作,现在它不-所以我不确定发生了什么。

其他回答

这将为现代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)使用的标题“Error”。

它不应该崩溃在旧的浏览器,而只是返回空数组。如果你需要更通用的解决方案,请查看stacktrace.js。它支持的浏览器列表确实令人印象深刻,但在我看来,对于它所打算执行的小任务来说,它太大了:37Kb的精简文本,包括所有依赖项。

对Eugene的回答进行了更新:为了让IE(特定版本?)填充堆栈属性,必须抛出错误对象。下面的例子应该比他现在的例子工作得更好,并且应该避免在IE中返回undefined。

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

注1:这类事情只应该在调试时执行,在运行时禁用,特别是频繁调用时。注2:这可能不能在所有浏览器中工作,但似乎可以在FF和IE 11中工作,这很适合我的需求。

在谷歌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

希望这对你有所帮助。

功能:

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

用例:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
<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>

这个脚本将显示错误