I have a function like this:
function foo() { throw new Error('`foo` has been removed in favor of `bar`') }
When someone calls foo
, I want the stack trace (error output) to point at the call site of foo
, not the throw
line inside of foo
.
For instance, I get this:
$ 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) ...
How do I get this instead?
$ 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) ...
Usually, a stack trace is shown when an Exception is not handled correctly in code. (An exception is what a runtime environment uses to tell you that there's an error in your code.) This may be one of the built-in Exception types, or a custom Exception created by a program or a library.
A Java stack trace is displayed when an error or exception occurs. The stack trace, also called a backtrace, consists of a collection of stack records, which store an application's movement during its execution.
In addition to telling you the exact line or function that caused a problem, a stack trace also tracks important metrics that monitor the health of your application. For example, if the average number of stack traces found in your logs increases, you know a bug has likely occurred.
Step 1: Define a custom Error object. For more information: A String is not an Error.
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;
Step 2: Use Domain
to catch the uncaught error.
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(); });
Step 3: Customize the output. The structured stack trace is an Array of CallSite objects, each of which represents a stack frame. A CallSite object defines these methods.
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
Run this program and we get the following output:
/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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With