The way to do this right is to return the result of the apply from the constructor, as well as setting the prototype in the usual complicated javascripty way:
function MyError() {
var tmp = Error.apply(this, arguments);
tmp.name = this.name = 'MyError'
this.stack = tmp.stack
this.message = tmp.message
return this
}
var IntermediateInheritor = function() {}
IntermediateInheritor.prototype = Error.prototype;
MyError.prototype = new IntermediateInheritor()
var myError = new MyError("message");
console.log("The message is: '"+myError.message+"'") // The message is: 'message'
console.log(myError instanceof Error) // true
console.log(myError instanceof MyError) // true
console.log(myError.toString()) // MyError: message
console.log(myError.stack) // MyError: message \n
// <stack trace ...>
The only problems with this way of doing it at this point (i've iterated it a bit) are that
- properties other than
stack
andmessage
aren't included inMyError
and - the stacktrace has an additional line that isn't really necessary.
The first problem could be fixed by iterating through all the non-enumerable properties of error using the trick in this answer: Is it possible to get the non-enumerable inherited property names of an object?Is it possible to get the non-enumerable inherited property names of an object?, but this isn't supported by ie<9. The second problem could be solved by tearing out that line in the stack trace, but I'm not sure how to safely do that (maybe just removing the second line of e.stack.toString() ??).