Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheriting from the Error object - where is the message property?

Tags:

javascript

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.

like image 638
Philippe Plantier Avatar asked Jan 10 '12 11:01

Philippe Plantier


People also ask

What are the two properties will actually create an error object?

JavaScript will actually create an Error object with two properties: name and message.

How do you make an error message in JavaScript?

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.

What is an error object?

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.


1 Answers

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

  • properties other than stack and message aren't included in MyError, 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?, 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

like image 64
B T Avatar answered Oct 12 '22 05:10

B T