Error subclasses may lose their message property

You have probably already seen a code like this:

try {
  throw new Error('Oh, nooooo!');
} catch (e) {
  console.log(e.message);            // Oh, nooooo!
  console.log(e instanceof Error);   // true
}

If you create many of those blocks, sooner or later you will decide that you are going to use custom error classes, even in JavaScript. It may seem to be a great idea to implement them this way:

function OhNoooError() {
  Error.call(this, "Oh, nooooo!");
  this.name = "OhNoooError";
}

But you may be surprised by the results:

try {
  throw new OhNoooError();
} catch (e) {
  console.log(e.message);                 // undefined
  console.log(e instanceof OhNoooError);  // true
  console.log(e instanceof Error);        // false
}

So the error you catch is not a classic error (does not inherit from the Error base class), and it does not have a message property! Oh, nooooooooooo!

Here is one way to fix it:

OhNoooError.prototype = Object.create(Error.prototype);
OhNoooError.prototype.constructor = OhNoooError;

function OhNoooError() {
  this.message = "Oh, nooooo!";
  this.name = "OhNoooError";
}

And now you have a much nicer output:

try {
  throw new OhNoooError();
} catch (e) {
  console.log(e.message);                 // Oh, nooooo!
  console.log(e instanceof OhNoooError);  // true
  console.log(e instanceof Error);        // true
}

The point is that you have to set the message property explicitly in the derived class – even if you use the extends keyword in CoffeeScript to do the inheritance magic.

 

Technorati-címkék: ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s