如果我自己抛出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
.
编辑2(2017):
在所有现代浏览器中,您只需调用:console.trace();
(MDN参考)
编辑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);
}
请注意,chrome/chrome(使用V8的其他浏览器)以及Firefox都有一个方便的界面来通过Error对象上的堆栈属性获取堆栈跟踪.
try { // Code throwing an exception } catch(e) { console.log(e.stack); }
它适用于基本异常以及您自己抛出的异常.(认为你使用的是Error类,这无论如何都是一种很好的做法).
查看有关V8文档的详细信息
在Firefox中,您似乎不需要抛出异常.这足够了
e = new Error(); console.log(e.stack);
如果您有firebug,则脚本选项卡中的所有错误选项都会中断.一旦脚本达到你的断点,你可以看看firebug的堆栈窗口:
原始问题的评论中指出的一个好的(简单的)解决方案是使用对象的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
对象中的设置!您可以在轨迹线之间添加间距并将其完全关闭.这里Console.trace
设置为false
:
您甚至可以关闭显示的第一位信息(设置Console.settings.debug.showInfo
为false
)或完全禁用调试(设置Console.settings.debug.enabled
为false
),这样您就不必再次注释掉调试语句!让他们进去,这将无能为力.
我不认为你可以使用任何内置的东西,但我确实找到了很多人自己动手的例子.
DIY javascript堆栈跟踪
任何浏览器中的Javascript堆栈跟踪
即使您抛出它,也可以访问实例的stack
(stacktrace
在Opera中)属性Error
.问题是,你需要确保你使用throw new Error(string)
(不要忘记新的而不是throw string
.
例:
try { 0++; } catch (e) { var myStackTrace = e.stack || e.stacktrace || ""; }
使用Chrome浏览器,您可以使用以下console.trace
方法:https://developer.chrome.com/devtools/docs/console-api#consoletraceobject
这将为现代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.它支持的浏览器列表真的很令人印象深刻,但在我看来,这对于它的小任务非常重要:37Kb的缩小文本,包括所有依赖项.
在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()
显示堆栈跟踪.
更新Eugene的答案:必须抛出错误对象,以便IE(特定版本?)填充stack
属性.以下应该比他当前的例子更好,并且应该避免undefined
在IE中返回.
function stackTrace() { try { var err = new Error(); throw err; } catch (err) { return err.stack; } }
注1:这种事情只应在调试时完成,并在实时时禁用,特别是在频繁调用时.注意2:这可能不适用于所有浏览器,但似乎适用于FF和IE 11,这很适合我的需要.