Extending Error in Javascript with ES6 syntax & Babel

Karel Bílek picture Karel Bílek · Jun 27, 2015 · Viewed 60.7k times · Source

I am trying to extend Error with ES6 and Babel. It isn't working out.

class MyError extends Error {
  constructor(m) {
    super(m);
  }
}

var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string

The Error object never get the right message set.

Try in Babel REPL.

Now I have seen a few solutions on SO (for example here), but they all seem very un-ES6-y. How to do it in a nice, ES6 way? (That is working in Babel)

Answer

Lee Benson picture Lee Benson · Sep 23, 2015

Based on Karel Bílek's answer, I'd make a small change to the constructor:

class ExtendableError extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
    if (typeof Error.captureStackTrace === 'function') {
      Error.captureStackTrace(this, this.constructor);
    } else { 
      this.stack = (new Error(message)).stack; 
    }
  }
}    

// now I can extend

class MyError extends ExtendableError {}

var myerror = new MyError("ll");
console.log(myerror.message);
console.log(myerror instanceof Error);
console.log(myerror.name);
console.log(myerror.stack);

This will print MyError in the stack, and not the generic Error.

It will also add the error message to the stack trace - which was missing from Karel's example.

It will also use captureStackTrace if it's available.

With Babel 6, you need transform-builtin-extend (npm) for this to work.