Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reduce stack trace when throwing error (point to call site)

Tags:

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)     ... 
like image 847
Jo Liss Avatar asked Mar 29 '14 00:03

Jo Liss


People also ask

What causes stack trace?

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.

What is error stack trace?

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.

What information can be found in a debugging stack trace that can be helpful when troubleshooting?

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.


1 Answers

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) 
like image 130
bnuhero Avatar answered Oct 05 '22 22:10

bnuhero