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
This works for me:
/**
* @class AuthorizationError
* @extends {Error}
*/
export class AuthorizationError extends Error {
message = 'UNAUTHORIZED';
name = 'AuthorizationError';
}
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.
Quoting
class MyError extends Error {
constructor(message) {
super(message);
this.message = message;
this.name = 'MyError';
}
}
There is no need for
this.stack = (new Error()).stack;
trick thanks tosuper()
call.
Although the above codes cannot output the stack trace unless this.stack = (new Error()).stack;
or Error.captureStackTrace(this, this.constructor.name);
is invoked in Babel. IMO, it maybe one issue in here.
Actually, the stack trace can be output under Chrome console
and Node.js v4.2.1
with this code snippets.
class MyError extends Error{
constructor(msg) {
super(msg);
this.message = msg;
this.name = 'MyError';
}
};
var myerr = new MyError("test");
console.log(myerr.stack);
console.log(myerr);
Output of Chrome console
.
MyError: test
at MyError (<anonymous>:3:28)
at <anonymous>:12:19
at Object.InjectedScript._evaluateOn (<anonymous>:875:140)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:808:34)
at Object.InjectedScript.evaluate (<anonymous>:664:21)
Output of Node.js
MyError: test
at MyError (/home/bsadmin/test/test.js:5:8)
at Object.<anonymous> (/home/bsadmin/test/test.js:11:13)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Function.Module.runMain (module.js:467:10)
at startup (node.js:134:18)
at node.js:961:3
Not using Babel, but in plain ES6, the following seems to work fine for me:
class CustomError extends Error {
constructor(...args) {
super(...args);
this.name = this.constructor.name;
}
}
Testing from REPL:
> const ce = new CustomError('foobar');
> ce.name
'CustomError'
> ce.message
'foobar'
> ce instanceof CustomError
true
> ce.stack
'CustomError: foobar\n at CustomError (repl:3:1)\n ...'
As you can see, the stack contains both the error name and message. I'm not sure if I'm missing something, but all the other answers seem to over-complicate things.
I am trying to extend Error with ES6
That class MyError extends Error {…}
syntax is correct.
Notice that transpilers still do have problems with inheriting from builtin objects. In your case,
var err = super(m);
Object.assign(this, err);
seems to fix the problem.
Edit: Breaking changes in Typescript 2.1
Extending built-ins like Error, Array, and Map may no longer work.
As a recommendation, you can manually adjust the prototype immediately after any super(...) calls.
Editing Lee Benson original answer a little bit works for me. This also adds stack
and additional methods of ExtendableError
class to the instance.
class ExtendableError extends Error {
constructor(message) {
super(message);
Object.setPrototypeOf(this, ExtendableError.prototype);
this.name = this.constructor.name;
}
dump() {
return { message: this.message, stack: this.stack }
}
}
class MyError extends ExtendableError {
constructor(message) {
super(message);
Object.setPrototypeOf(this, MyError.prototype);
}
}
var myerror = new MyError("ll");
console.log(myerror.message);
console.log(myerror.dump());
console.log(myerror instanceof Error);
console.log(myerror.name);
console.log(myerror.stack);