I have defined the following object
const AuthErrorCode = {
EMAIL_ALREADY_EXISTS: {
code: "auth/email-already-exists",
message: "Hello world!"
},
... more error codes
};
And I am implementing a class that extends Error
class AuthError extends Error {
constructor(code, message = undefined) {
switch(code) {
case "EMAIL_ALREADY_EXISTS":
code = AuthErrorCode[code].code;
message = message ?? AuthErrorCode[code].message;
break;
default:
throw new Error("Invalid code");
}
super(message);
Object.assign(this, {
code,
name: "AuthError",
});
}
}
which is supposed to receive a code and an optional custom message.
This class has to check that the given code is in the AuthErrorCode object (EMAIL_ALREADY_EXISTS || "auth/email-already-exists" are valid). If it is not inside it, then some kind of feedback should be displayed to the programmer (an error or something). I mean, I need to make sure that the code is a valid AuthErrorCode, because if not, the class is being used incorrectly.
How can I do that? Is it possible?
For example, this code must fail:
throw new AuthError("auth/some-invented-code", "Hello world!");
Example of correct use:
throw new AuthError("EMAIL_ALREADY_EXISTS", "Hello world!");
throw new AuthError("auth/email-already-exists");
AuthErrorclass would extendAuthErrorCodeclass which would extendError. That would allow the AuthErrorCode to determine its own fate. If the 'is a' relationship is uncomfortable for you, you can always encapsulate theAuthErrorCodeclass. As you have it written right now this will throw:AuthErrorCode[code].messageif the code doesn't exist. So that certainly doesn't achieve your goal.