I noticed a strange behavior while defining custom error objects in Javascript:
function MyError(msg) { Error.call(this, msg); this.name = "MyError"; } MyError.prototype.__proto__ = Error.prototype; var error = new Error("message"); error.message; // "message" var myError = new MyError("message"); myError instanceof Error; // true myError.message; // "" !
Why does new Error("message")
set the message
property, while Error.call(this, msg);
does not? Sure, I can just define this.message = msg
in the MyError
constructor, but I don't quite understand why it is not already set in the first place.
JavaScript will actually create an Error object with two properties: name and message.
In JavaScript error message property is used to set or return the error message. Return Value: It returns a string, representing the details of the error. More example codes for the above property are as follows: Example 1: This example does not contains any error so it does not display error message.
The error object is a built-in object that provides a standard set of useful information when an error occurs, such as a stack trace and the error message.
A. Like, Raynos said, The reason message
isn't being set is that Error
is a function that returns a new Error object and does not manipulate this
in any way.
B. The way to do this right is to set the result of the apply from the constructor on this
, 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.message = tmp.message // instead of this.stack = ..., a getter for more optimizy goodness Object.defineProperty(this, 'stack', { get: function () { return tmp.stack } }) 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 iteratted it a bit) are that
stack
and message
aren't included in MyError
, andThe 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?, 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() ??).
Update
I created an inheritance library that does this ^ https://github.com/fresheneesz/proto
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With