JavaScript:抛出错误时减less堆栈跟踪(指向调用站点)

我有这样的function:

function foo() { throw new Error('`foo` has been removed in favor of `bar`') } 

当某人调用foo ,我希望堆栈跟踪(错误输出)指向foo的调用位置,而不是foothrow行。

例如,我得到这个:

 $ 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)