Error.name

# Kevin Smith (12 years ago)

I see that the Error constructor is designed to be subclassable. I can create simple error types like so:

class ZenError extends Error {}

let err = new ZenError("abc");

However, I would expect that:

err.name === "ZenError";

Such an expectation would be useful when determining how to deal with a trapped error, and using such a technique would avoid the cross-realm and cross-library-instance problems inherent with instanceof.

In any case, this is useless:

err.name === "Error";

I could, of course, do this manually:

class ZenError extends Error {
    constructor(msg) { super(msg); this.name = this.constructor.name; }
}

Or even create an intermediate class which does this:

class CustomError extends Error {
    constructor(msg) { super(msg); this.name = this.constructor.name; }
}

class ZenError extends CustomError { }

But I can't imaging ever not wanting to have the name property of the error object equal the name of the constructor which created it.

Thoughts?

# Domenic Denicola (12 years ago)

+1 to making this work seamlessly, if possible. But I am not sure it is possible...

From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Kevin Smith

I could, of course, do this manually:

class ZenError extends Error {         constructor(msg) { super(msg); this.name = this.constructor.name; }     }

Actually, this isn't even "correct" by ES spec standards---illustrating how error-prone this kind of manual setup is. That is, the error types in ES have .prototype.name properties on the constructor, not own .name properties. So the correct manual setup is

class ZenError extends Error {
}
ZenError.prototype.name = ZenError.name;

The only way I can think of to fix this is to change the Error.prototype.name property to a getter that returns this.constructor.name. But now all existing code that does not set name correctly has suddenly had its meaning, and observable side effects, changed. Seems unlikely to be web compatible. (Plus you have to create a setter and handle the cases when people do set it to something.)

You then start thinking, well, maybe we should make a simple opt-in to the more correct behavior. But, can you really make it more simple than ZenError.prototype.name = ZenError.name? I guess Error.fixSubclassName(ZenError) is a bit more DRY, but not by much.

Would be curious if anyone has any solutions, but I'm not sure there are any :(. 100% correct Error subclassing might have to remain a mistake-prone process.

# Andrea Giammarchi (12 years ago)

the way I've solved that a while ago ( code.google.com/p/formaldehyde/source/browse/trunk/formaldehyde.js )

(ServerError.prototype = new Error).name = "ServerError";

Today I would do

function ServerError(message) {
  this.message = '' + message;
}
ServerError.prototype = Object.setPrototypeOf({
  name: ServerError.name
}, Error.prototype);