0
var Controller = function () {

try {
    throw new this.userException('test', 'test');
  } catch (error) {
    if (error instanceof this.userException) {
      console.error(error.stack);
    }
  }
}


Controller.prototype.userException = function (name, message, htmlMessage) {
  this.name = name;
  this.message = message;
  this.htmlMessage = htmlMessage;
  Error.captureStackTrace(this, this.userException);
  this.toString = function () {
    return name + ' : ' + message;
  }
};

While I was trying to create custom exceptions i found this Error.captureStackTrace in Node JS document. First i used it like below.

Error.captureStackTrace(this, userException);

Which console.error(error) gave no output.By mistake I changed the line to

Error.captureStackTrace(this, this.userException);

Which return object the contains properties of userException methods. Also console.error(error.stack); prints the stack trace. I'm so confused how does this keyword works in this statement Error.captureStackTrace(this, this.userException);. what are this keywords of first and second arguments pointed to? is it to the same Controller object? But again, why i had to provide this as the first and second argument, in order this to work?

s1n7ax
  • 1,567
  • 4
  • 16
  • 32

1 Answers1

0

Because you're calling userException via new, this within it is the new object created by the new operator. This is different from now you normally call prototype functions and suggests that userException probably shouldn't be on Controller.prototype.

Your code was failing when you didn't have this.userException because it was expecting that there would be an in-scope userException identifier, but there wasn't (it's a property of the controller prototype, not a freestanding identifier).

It started working when you added this. in front of it because that no longer looks for a freestanding identifier, it looks for a property of this with that name. There isn't any, but that's fine, it just ends up passing undefined into captureStackTrace.

Looking at what I can find for captureStackTrace, the second argument is optional and if given is expected to be a function, so presumably it's just ignoring the undefined you give it and you could/should be doing Error.captureStackTrace(this); instead.

Related:

Note that subclassing Error is quite difficult in ES5 and earlier; don't try to roll your own, use something someone's already built for you. The nice folks behind Babel (the JavaScript transpiler you can use to use ES2015 [and beyond] on ES5 JavaScript engines) have done that work for you. You could use ES2015's class syntax to extend Error and use Babel to transpile. But that might be overkill for whatever you're trying to do.

Community
  • 1
  • 1
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639