2016-10-06 07:27:35 -05:00
|
|
|
var _ = require('lodash'),
|
2017-01-04 11:10:29 -05:00
|
|
|
uuid = require('uuid'),
|
2016-10-06 07:27:35 -05:00
|
|
|
util = require('util');
|
|
|
|
|
|
|
|
function GhostError(options) {
|
|
|
|
options = options || {};
|
2016-10-10 12:30:30 -05:00
|
|
|
var self = this;
|
2016-10-06 07:27:35 -05:00
|
|
|
|
|
|
|
if (_.isString(options)) {
|
|
|
|
throw new Error('Please instantiate Errors with the option pattern. e.g. new errors.GhostError({message: ...})');
|
|
|
|
}
|
|
|
|
|
|
|
|
Error.call(this);
|
|
|
|
Error.captureStackTrace(this, GhostError);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* defaults
|
|
|
|
*/
|
|
|
|
this.statusCode = 500;
|
|
|
|
this.errorType = 'InternalServerError';
|
|
|
|
this.level = 'normal';
|
2016-10-21 07:10:17 -05:00
|
|
|
this.id = uuid.v1();
|
2016-10-06 07:27:35 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* custom overrides
|
|
|
|
*/
|
|
|
|
this.statusCode = options.statusCode || this.statusCode;
|
|
|
|
this.level = options.level || this.level;
|
|
|
|
this.context = options.context || this.context;
|
|
|
|
this.help = options.help || this.help;
|
|
|
|
this.errorType = this.name = options.errorType || this.errorType;
|
|
|
|
this.errorDetails = options.errorDetails;
|
2016-10-12 10:18:57 -05:00
|
|
|
this.code = options.code || null;
|
2016-10-06 07:27:35 -05:00
|
|
|
|
|
|
|
// @TODO: ?
|
|
|
|
this.property = options.property;
|
|
|
|
this.value = options.value;
|
|
|
|
|
|
|
|
this.message = options.message;
|
|
|
|
this.hideStack = options.hideStack;
|
|
|
|
|
|
|
|
// error to inherit from, override!
|
2016-10-10 12:30:30 -05:00
|
|
|
// nested objects are getting copied over in one piece (can be changed, but not needed right now)
|
2016-10-06 07:27:35 -05:00
|
|
|
if (options.err) {
|
2016-11-09 03:13:50 -05:00
|
|
|
// it can happen that third party libs return errors as strings, yes really
|
|
|
|
// we are creating an error stack from this line, but we need to ensure not loosing the original error message
|
|
|
|
if (_.isString(options.err)) {
|
|
|
|
options.err = new Error(options.err);
|
|
|
|
}
|
|
|
|
|
2016-10-10 12:30:30 -05:00
|
|
|
Object.getOwnPropertyNames(options.err).forEach(function (property) {
|
2016-11-09 03:13:50 -05:00
|
|
|
// original message is part of the stack, no need to pick it
|
2016-10-10 12:30:30 -05:00
|
|
|
if (['errorType', 'name', 'statusCode'].indexOf(property) !== -1) {
|
|
|
|
return;
|
|
|
|
}
|
2016-11-09 03:13:50 -05:00
|
|
|
|
|
|
|
if (property === 'message' && !self[property]) {
|
|
|
|
self[property] = options.err[property];
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (property === 'stack') {
|
|
|
|
self[property] += '\n\n' + options.err[property];
|
|
|
|
return;
|
|
|
|
}
|
2016-10-10 12:30:30 -05:00
|
|
|
|
|
|
|
self[property] = options.err[property] || self[property];
|
|
|
|
});
|
2016-10-06 07:27:35 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// jscs:disable
|
|
|
|
var errors = {
|
|
|
|
DataExportError: function DataExportError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 500,
|
|
|
|
errorType: 'DataExportError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
DataImportError: function DataImportError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 500,
|
|
|
|
errorType: 'DataImportError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
IncorrectUsageError: function IncorrectUsageError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 400,
|
|
|
|
level: 'critical',
|
|
|
|
errorType: 'IncorrectUsageError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
NotFoundError: function NotFoundError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 404,
|
|
|
|
errorType: 'NotFoundError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
BadRequestError: function BadRequestError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 400,
|
|
|
|
errorType: 'BadRequestError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
DatabaseVersionError: function DatabaseVersionError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
hideStack: true,
|
|
|
|
statusCode: 500,
|
|
|
|
errorType: 'DatabaseVersionError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
DatabaseNotPopulatedError: function DatabaseNotPopulatedError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 500,
|
|
|
|
errorType: 'DatabaseNotPopulatedError'
|
|
|
|
}, options));
|
|
|
|
},
|
2016-10-06 08:50:55 -05:00
|
|
|
DatabaseNotSeededError: function DatabaseNotSeededError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 500,
|
|
|
|
errorType: 'DatabaseNotSeededError'
|
|
|
|
}, options));
|
|
|
|
},
|
2016-10-06 07:27:35 -05:00
|
|
|
UnauthorizedError: function UnauthorizedError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 401,
|
|
|
|
errorType: 'UnauthorizedError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
NoPermissionError: function NoPermissionError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 403,
|
|
|
|
errorType: 'NoPermissionError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
ValidationError: function ValidationError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 422,
|
|
|
|
errorType: 'ValidationError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
UnsupportedMediaTypeError: function UnsupportedMediaTypeError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 415,
|
|
|
|
errorType: 'UnsupportedMediaTypeError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
VersionMismatchError: function VersionMismatchError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 400,
|
|
|
|
errorType: 'VersionMismatchError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
TokenRevocationError: function TokenRevocationError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 503,
|
|
|
|
errorType: 'TokenRevocationError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
EmailError: function EmailError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 500,
|
|
|
|
errorType: 'EmailError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
TooManyRequestsError: function TooManyRequestsError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 429,
|
|
|
|
errorType: 'TooManyRequestsError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
MaintenanceError: function MaintenanceError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 503,
|
|
|
|
errorType: 'MaintenanceError'
|
|
|
|
}, options));
|
|
|
|
},
|
|
|
|
ThemeValidationError: function ThemeValidationError(options) {
|
|
|
|
GhostError.call(this, _.merge({
|
|
|
|
statusCode: 422,
|
|
|
|
errorType: 'ThemeValidationError',
|
|
|
|
errorDetails: {}
|
|
|
|
}, options));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-10-19 09:27:22 -05:00
|
|
|
util.inherits(GhostError, Error);
|
2016-10-06 07:27:35 -05:00
|
|
|
_.each(errors, function (error) {
|
|
|
|
util.inherits(error, GhostError);
|
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = errors;
|
|
|
|
module.exports.GhostError = GhostError;
|
|
|
|
|
|
|
|
|