Here's how you could create custom error classes in Node.js using latest ES6 / ES2015 syntax.
I've tried to make it as lean and unobtrusive as possible.
errors/AppError.js
module.exports = class AppError extends Error {
constructor (message, status) {
// Calling parent constructor of base Error class.
super(message);
// Saving class name in the property of our custom error as a shortcut.
this.name = this.constructor.name;
// Capturing stack trace, excluding constructor call from it
// (this is probably no longer required in node >=8, see the comments)
Error.captureStackTrace(this, this.constructor);
// You can use any additional properties you want.
// I'm going to use preferred HTTP status for this error types.
// `500` is the default value if not specified.
this.status = status || 500;
}
};
errors/EmailTakenError.js
module.exports = class EmailTakenError extends require('./errors/AppError') {
constructor (message) {
// Providing default message and overriding status code.
super(message || 'Specified E-Mail is already taken', 400);
}
};
errors/RequestValidationError.js
module.exports = class extends require('./AppError') {
constructor (fields) {
// Overriding both message and status code.
super('Request validation failed', 400);
// Saving custom property.
this.fields = fields || {};
}
};
const AppError = require('./../api/errors/AppError');
const EmailTakenError = require('./../api/errors/EmailTakenError');
const RequestValidationError = require('./../api/errors/RequestValidationError');
try {
// Throwing EmailTakenError exception.
throw new EmailTakenError();
} catch (error) {
// Catching exception by class.
if (error instanceof EmailTakenError) {
console.log('E-Mail validation failed!', error);
} else {
// If failed to catch, throwing it higher.
console.log('Unknown error', error);
throw error;
}
}
try {
// Throwing RequestValidationError exception.
throw new RequestValidationError();
} catch (error) {
// Catching error by base (parent) class.
if (error instanceof AppError) {
console.log('Some application error occurred!', error);
} else {
console.log('Unknown error', error);
throw error;
}
}
It works great for my application, however criticism is welcomed.
Just a small order fix
This way the stacktrace will hold the name as well