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.
I've run your code a few times and noticed that in the
Node.js 8.11.2
I'm getting the same output with and withoutError.captureStackTrace(this, this.constructor);
line in theAppError.js
constructor.It looks like in the
Node.js 8.11.2
and above it's the default behavior. If we're extendingError
class, we don't need to usecaptureStackTrace
to omit all frames abovethis.constructor
.Please, take a look at the documentation. The most important part:
.stack
will be added automatically.Please let me know if I am not correct.