I like to do it like this, making use of name and message allows the error to be the same whether it’s in a stacktrace or a toString():

class AppException extends Error {
constructor(code, message) {
const fullMsg = message ? `${code}: ${message}` : code;
super(fullMsg);
this.name = code;
this.message = fullMsg;
}

toString() {
return this.message;
}
}
// Just an error name
try {
throw new AppException('Forbidden');
} catch(e) {
console.error(e);
console.error(e.toString());
}
// A name and a message
try {
throw new AppException('Forbidden', 'You don\'t have access to this page');
} catch(e) {
console.error(e);
console.error(e.toString());
}

I make UIs and such. Using JS mostly but I like to dabble.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store