JavaScript:抛出错误时减less堆栈跟踪(指向调用站点)
我有这样的function:
function foo() { throw new Error('`foo` has been removed in favor of `bar`') }
当某人调用foo
,我希望堆栈跟踪(错误输出)指向foo
的调用位置,而不是foo
的throw
行。
例如,我得到这个:
$ node test.js /home/ubuntu/tmp/test.js:2 throw new Error('`foo` has been removed in favor of `bar`') ^ Error: `foo` has been removed in favor of `bar` at foo (/home/ubuntu/tmp/test.js:2:9) at Object.<anonymous> (/home/ubuntu/tmp/test.js:5:1) ...
我怎样才能得到这个呢?
$ node test.js /home/ubuntu/tmp/test.js:5 foo() ^ Error: `foo` has been removed in favor of `bar` at Object.<anonymous> (/home/ubuntu/tmp/test.js:5:1) ...
第1步:定义一个自定义的错误对象。 有关更多信息: string不是一个错误 。
function CustomError (msg) { Error.call(this); // By default, V8 limits the stack trace size to 10 frames. Error.stackTraceLimit = 10; // Customizing stack traces Error.prepareStackTrace = function (err, stack) { return stack; }; Error.captureStackTrace(this, arguments.callee); this.message = msg; this.name = 'CustomError'; }; CustomError.prototype.__proto__ = Error.prototype;
第2步:使用Domain
来捕获未捕获的错误。
function foo() { throw new CustomError('`foo` has been removed in favorof `bar`'); }; var d = require('domain').create(); d.on('error', function(err) { /* * customize the output here. */ }); d.run(function() { foo(); });
第3步:自定义输出。 结构化堆栈跟踪是一个CallSite对象数组,每个对象表示一个堆栈帧。 CallSite对象定义了这些方法 。
for(var index=0; index<err.stack.length; index++){ var frame = err.stack[index]; var unit = frame.getFunctionName() || frame.getMethodName(); if (unit === null) { unit = 'function()'; } else { unit += '()' } if (index === 0) { console.error('%s:%d:%d\n %s\n ^', frame.getFileName(), frame.getLineNumber(), frame.getColumnNumber(), unit); console.error('Error: ' + err.message); } else { console.error(' at %s (%s:%d:%d)', unit, frame.getFileName(), frame.getLineNumber(), frame.getColumnNumber()); }; }; // END. stack trace
运行这个程序,我们得到以下输出:
/home/ray/dev/test/error.js:57:9 foo() ^ Error: `foo` has been removed in favorof `bar` at function() (/home/ray/dev/test/error.js:53:3) at b() (domain.js:183:18) at Domain.run() (domain.js:123:23) at function() (/home/ray/dev/test/error.js:52:3) at Module._compile() (module.js:456:26) at Module._extensions..js() (module.js:474:10) at Module.load() (module.js:356:32) at Module._load() (module.js:312:12) at Module.runMain() (module.js:497:10)