当我抛出异常时,如何获取JavaScript堆栈跟踪?

当我抛出异常时,如何获取JavaScript堆栈跟踪?,javascript,stack-trace,Javascript,Stack Trace,如果我自己抛出一个JavaScript异常(例如,抛出“aarrgg”),我如何获得堆栈跟踪(在Firebug或其他情况下)?现在我刚得到消息 编辑:正如下面许多人所发布的,可以获取JavaScript异常的堆栈跟踪,但我想获取异常的堆栈跟踪。例如: function foo() { bar(2); } function bar(n) { if (n < 2) throw "Oh no! 'n' is too small!" bar(n-1); }

如果我自己抛出一个JavaScript异常(例如,
抛出“aarrgg”
),我如何获得堆栈跟踪(在Firebug或其他情况下)?现在我刚得到消息

编辑:正如下面许多人所发布的,可以获取JavaScript异常的堆栈跟踪,但我想获取异常的堆栈跟踪。例如:

function foo() {
    bar(2);
}
function bar(n) {
    if (n < 2)
        throw "Oh no! 'n' is too small!"
    bar(n-1);
}
/* 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();
函数foo(){
酒吧(2);
}
功能条(n){
if(n<2)
抛出“哦,不!n’太小了!”
巴(n-1);
}

当调用
foo
时,我想得到一个堆栈跟踪,其中包括对
foo
bar
bar
,的调用。我不认为有任何内置的东西可以使用,但是我确实发现了很多人自己滚动的例子


如果您有firebug,则“脚本”选项卡中的“所有错误”选项都会中断。脚本到达断点后,可以查看firebug的堆栈窗口:


在Firefox上获取堆栈跟踪比在IE上更容易,但基本上,以下是您想要做的:

将“有问题”的代码段包装在try/catch块中:

try {
    // some code that doesn't work
    var t = null;
    var n = t.not_a_value;
}
    catch(e) {
}
如果要检查“error”对象的内容,它包含以下字段:

e、 文件名:问题来源的源文件/页面 e、 lineNumber:出现问题的文件/页面中的行号 e、 消息:一条简单的消息,描述发生的错误类型 e、 名称:发生的错误类型,在上面的示例中应为“TypeError” e、 堆栈:包含导致异常的堆栈跟踪

我希望这对你有所帮助。

编辑2(2017):

在所有现代浏览器中,您只需调用:
console.trace()

编辑1(2013):

正如在对原始问题的评论中指出的,更好(更简单)的解决方案是使用
错误
对象的
堆栈
属性,如下所示:

函数stackTrace(){
var err=新错误();
返回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、 回调/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x、 回调/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
.发送/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
给出调用函数的名称以及URL、其调用函数等

原创(2009):

的修改版本可能会有所帮助:

函数stacktrace(){
功能st2(f){
返回!f?[]:
st2(f.caller).concat([f.toString().split('(')[0])。子字符串(9)+'('+f.arguments.join(',')+')));
}
返回st2(arguments.callee.caller);
}

您可以访问
错误实例的
堆栈
stacktrace
在Opera中)属性,即使您抛出了它。问题是,您需要确保使用
抛出新错误(字符串)
(不要忘记新建而不是
抛出字符串

例如:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}
请注意,chrome/chrome(其他使用V8的浏览器)和Firefox都有一个方便的界面,可以通过错误对象的堆栈属性获取stacktrace

它既适用于基本异常,也适用于您自己抛出的异常(考虑到您使用的是Error类,这是一个很好的实践)


请参阅

获取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()
显示堆栈跟踪。

在Google Chrome(19.0及更高版本)中,只需抛出异常即可完美工作。例如:

function foo() {
    bar(2);
}
function bar(n) {
    if (n < 2)
        throw "Oh no! 'n' is too small!"
    bar(n-1);
}
/* 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

希望对您有所帮助。

在Firefox中,您似乎不需要抛出异常。这就足够了

e = new Error();
console.log(e.stack);
正如在对原始问题的评论中指出的,一个好的(简单的)解决方案是使用
错误
对象的
堆栈
属性,如下所示:

函数stackTrace(){
var err=新错误();
返回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、 回调/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x、 回调/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
.发送/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
给出调用函数的名称以及URL和行号、调用函数等

我有一个非常详细和漂亮的解决方案,我为我目前正在进行的一个项目设计了这个解决方案,我对它进行了提取和修改,使其更具普遍性。这里是:

(函数(上下文){
//只有全局名称空间。
变量控制台={
//背景
设置:{
调试:{
alwaysShowURL:false,
启用:对,
showInfo:对
},
堆栈跟踪:{
启用:对,
对,,
ignoreDebugFuncs:对,
间距:false
}
}
};
//字符串格式化原型函数。
if(!String.prototype.format){
String.prototype.format=函数(){
var s=this.toString(),
args=类型
try{ null.toString(); } catch(e) { alert(e.stack); }
<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>
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'));
function stackTrace() {
  try {
    var err = new Error();
    throw err;
  } catch (err) {
    return err.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)
            {

            }
        };
<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>
function print_call_stack(err) {
    var stack = err.stack;
    console.error(stack);
}
     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}
throw new Error('some error here')
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;
}
console.groupCollapsed('jjjjjjjjjjjjjjjjj')
    console.trace()
    try {
        throw "kuku"
    } catch(e) {
        console.log(e.stack)
    }
console.groupEnd()
traceUntillMe()