JavaScript error / exception extension

I was developing a small JS library and had to use special error exceptions there.

So, I decided to inherit them (ORLY?) From my own Javascript Error object like this:

var MyError = function(){ Error.prototype.constructor.apply(this, arguments); }; // Inherit without instantiating Error var Surrogate = function(){}; Surrogate.prototype = Error.prototype; MyError.prototype = new Surrogate(); // Add some original methods MyError.prototype.uniqueMethod = function(){...} 

It looks like ordinary inheritance .. But!

 var err = new MyError("hello! this is text!"); console.log(err.message); // is giving me empty string! 

I read articles about this here and MDN , but all of them told me to use something like this:

 var MyError = function(msg){ this.message = msg; }; 

But my question is: if not in the Error constructor, then where is the message initialized? Can anyone know how the error constructor works?

Thanks!

PS If this is interesting - I developed the Enum.js library.

+6
source share
1 answer

What you do is beautiful. This is Error , that is the problem.

In this line:

 Error.prototype.constructor.apply(this, arguments); 

... you call Error (indirectly) as a normal function call, and not as part of the new expression, but the defined behavior for Error , when you call it as a non-constructor function , is to create a new empty Error and return it (instead of filling this ).

Now, in the normal case, what you do with the prototype would do a standard check to see if it was called as a constructor ( if (this instanceof Error) ). Unfortunately, this does not seem to be the case, and any check that he uses to determine how it was called does not seem to immediately give in to what you are trying to do. Even this (this is just a test, not what you are actually doing):

 MyError.prototype = Error.prototype; // You wouldn't normally do this, it just a test 

... did not decide.

This answer to another question points to a possible workaround (basically, let Error create an object and then return this from MyError ):

 function MyError(message) { var e = new Error(message); // ...apply your enhancements to `e` return e; } 

Not surprisingly satisfactory, since you have to place your extensions directly on the object, and not use the prototype chain, but if Error refuses to play the ball, your options are a bit limited ...

+5
source

Source: https://habr.com/ru/post/948959/


All Articles