Skip to content

Commit

Permalink
🛠 use Ignition for logging/errors (#7869)
Browse files Browse the repository at this point in the history
no issue

- we started implementing logging and error handling in Ghost
- later we outsourced both into a module
- use the module now in Ghost
- this commit basically just removes the logging and error implementation and uses Ignition
  • Loading branch information
kirrg001 authored and kevinansfield committed Jan 23, 2017
1 parent 7cb57bf commit 78eacb1
Show file tree
Hide file tree
Showing 10 changed files with 34 additions and 732 deletions.
1 change: 1 addition & 0 deletions core/server/data/xml/xmlrpc.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ function ping(post) {
req.on('error', function handleError(err) {
logging.error(new errors.GhostError({
err: err,
message: err.message,
context: i18n.t('errors.data.xml.xmlrpc.pingUpdateFailed.error'),
help: i18n.t('errors.data.xml.xmlrpc.pingUpdateFailed.help', {url: 'http://support.ghost.org'})
}));
Expand Down
150 changes: 15 additions & 135 deletions core/server/errors.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,16 @@
var _ = require('lodash'),
uuid = require('uuid'),
util = require('util');
util = require('util'),
errors = require('ghost-ignition').errors;

function GhostError(options) {
options = options || {};
var self = this;

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';
this.id = uuid.v1();

/**
* 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;
this.code = options.code || null;

// @TODO: ?
this.property = options.property;
this.value = options.value;

this.message = options.message;
this.hideStack = options.hideStack;

// error to inherit from, override!
// nested objects are getting copied over in one piece (can be changed, but not needed right now)
if (options.err) {
// 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);
}

Object.getOwnPropertyNames(options.err).forEach(function (property) {
// original message is part of the stack, no need to pick it
if (['errorType', 'name', 'statusCode'].indexOf(property) !== -1) {
return;
}

if (property === 'message' && !self[property]) {
self[property] = options.err[property];
return;
}

if (property === 'stack') {
self[property] += '\n\n' + options.err[property];
return;
}

self[property] = options.err[property] || self[property];
});
}
errors.IgnitionError.call(this, options);
}

// jscs:disable
var errors = {
var ghostErrors = {
DataExportError: function DataExportError(options) {
GhostError.call(this, _.merge({
statusCode: 500,
Expand All @@ -83,25 +23,6 @@ var errors = {
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,
Expand All @@ -121,60 +42,12 @@ var errors = {
errorType: 'DatabaseNotSeededError'
}, options));
},
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,
Expand All @@ -184,12 +57,19 @@ var errors = {
}
};

util.inherits(GhostError, Error);
_.each(errors, function (error) {
util.inherits(GhostError, errors.IgnitionError);
_.each(ghostErrors, function (error) {
util.inherits(error, GhostError);
});

module.exports = errors;
module.exports.GhostError = GhostError;
// we need to inherit all general errors from GhostError, otherwise we have to check instanceof IgnitionError
_.each(errors, function (error) {
if (error.name === 'IgnitionError' || typeof error === 'object') {
return;
}

util.inherits(error, GhostError);
});

module.exports = _.merge(ghostErrors, errors);
module.exports.GhostError = GhostError;
12 changes: 12 additions & 0 deletions core/server/logging.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var config = require('./config'),
logging = require('ghost-ignition').logging;

module.exports = logging({
env: config.get('env'),
path: config.get('logging:path') || config.getContentPath('logs'),
domain: config.get('url').replace(/[^\w]/gi, '_'),
mode: config.get('logging:mode'),
level: config.get('logging:level'),
transports: config.get('logging:transports'),
loggly: config.get('logging:loggly')
});
Loading

0 comments on commit 78eacb1

Please sign in to comment.