I was developing a small JS library and was to use there custom Error exceptions.
So, I decided to inherit them (ORLY?) from native Javascript Error object in this way:
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(){...}
Looks like usual inheritance.. But!
var err = new MyError("hello! this is text!");
console.log(err.message); // is giving me empty string!
I have read articles about this here and on MDN, but all of them saying me to use something like this:
var MyError = function(msg){
this.message = msg;
};
But my question is - if not in the constructor of Error, then where message is initialized? May be somebody knows how Error native constructor works?
Thanks!
P.S. If it interesting - I was developing Enum.js library.
While the majority of exceptions are implementations of the global Error class, any old object can be thrown. With this in mind, there are two ways to throw an exception: directly via an Error object, and through a custom object.
In order to create custom exception, we need to extend Exception class that belongs to java.lang package. Consider the following example, where we create a custom exception named WrongFileNameException: public class WrongFileNameException extends Exception { public WrongFileNameException(String errorMessage) {
It's best to avoid throwing errors from inside a Promise, because they may not always be caught, depending on how the code that called them is structured. However it's good practice to return an error when rejecting a Promise, and you can return Error custom types just like any other Error.
What you're doing is fine. It's Error
that's the problem.
On this line:
Error.prototype.constructor.apply(this, arguments);
...you're calling Error
(indirectly) as a normal function call rather than as part of a new
expression, and the defined behavior for Error
when you call it as a non-constructor function is to create a new, blank Error
and return it (rather than populating this
).
Now, in the normal case, what you're doing with the prototype would make the standard check for whether it was called as a constructor (if (this instanceof Error)
) work. Unfortunately, it doesn't seem to be doing that, and whatever check it uses to determine how it was called doesn't seem to be immediately amenable to what you're trying to do. Even this (which is just a test, not meant to be something you'd actually do):
MyError.prototype = Error.prototype; // You wouldn't normally do this, it's just a test
...didn't solve it.
This answer to another Stack Overflow question points to a possible workaround (basically, let Error
create the object and then return that from MyError
):
function MyError(message) {
var e = new Error(message);
// ...apply your enhancements to `e`
return e;
}
Not amazingly satisfying as you'd have to put your extensions directly on the object rather than use the prototype chain, but if Error
refusees to play ball, your options are a bit limited...
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