mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-24 03:14:03 +03:00
Add distinct error classes
closes #2690 - added new error classes - moved errorhandling.js to /errors/index.js - changed API errors to use new classes - updated tests
This commit is contained in:
parent
d4a6eb26a4
commit
fd0f5a5028
2
core/bootstrap.js
vendored
2
core/bootstrap.js
vendored
@ -7,7 +7,7 @@
|
||||
var fs = require('fs'),
|
||||
url = require('url'),
|
||||
when = require('when'),
|
||||
errors = require('./server/errorHandling'),
|
||||
errors = require('./server/errors'),
|
||||
config = require('./server/config'),
|
||||
|
||||
appRoot = config().paths.appRoot,
|
||||
|
@ -6,7 +6,7 @@ var dataExport = require('../data/export'),
|
||||
nodefn = require('when/node/function'),
|
||||
_ = require('lodash'),
|
||||
validation = require('../data/validation'),
|
||||
errors = require('../../server/errorHandling'),
|
||||
errors = require('../../server/errors'),
|
||||
canThis = require('../permissions').canThis,
|
||||
api = {},
|
||||
db;
|
||||
@ -23,10 +23,10 @@ db = {
|
||||
return dataExport().then(function (exportedData) {
|
||||
return when.resolve({ db: [exportedData] });
|
||||
}).otherwise(function (error) {
|
||||
return when.reject({type: 'InternalServerError', message: error.message || error});
|
||||
return when.reject(new errors.InternalServerError(error.message || error));
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to export data. (no rights)'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to export data. (no rights)'));
|
||||
});
|
||||
},
|
||||
'importContent': function (options) {
|
||||
@ -43,7 +43,7 @@ db = {
|
||||
* - If there is no path
|
||||
* - If the name doesn't have json in it
|
||||
*/
|
||||
return when.reject({type: 'InternalServerError', message: 'Please select a .json file to import.'});
|
||||
return when.reject(new errors.InternalServerError('Please select a .json file to import.'));
|
||||
}
|
||||
|
||||
return api.settings.read.call({ internal: true }, { key: 'databaseVersion' }).then(function (response) {
|
||||
@ -65,11 +65,11 @@ db = {
|
||||
importData = JSON.parse(fileContents);
|
||||
} catch (e) {
|
||||
errors.logError(e, "API DB import content", "check that the import file is valid JSON.");
|
||||
return when.reject(new Error("Failed to parse the import JSON file"));
|
||||
return when.reject(new errors.BadRequest("Failed to parse the import JSON file"));
|
||||
}
|
||||
|
||||
if (!importData.meta || !importData.meta.version) {
|
||||
return when.reject(new Error("Import data does not specify version"));
|
||||
return when.reject(new errors.ValidationError("Import data does not specify version", 'meta.version'));
|
||||
}
|
||||
|
||||
_.each(_.keys(importData.data), function (tableName) {
|
||||
@ -94,13 +94,13 @@ db = {
|
||||
}).then(function () {
|
||||
return when.resolve({ db: [] });
|
||||
}).otherwise(function importFailure(error) {
|
||||
return when.reject({type: 'InternalServerError', message: error.message || error});
|
||||
return when.reject(new errors.InternalServerError(error.message || error));
|
||||
}).finally(function () {
|
||||
// Unlink the file after import
|
||||
return nodefn.call(fs.unlink, options.importfile.path);
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to export data. (no rights)'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to export data. (no rights)'));
|
||||
});
|
||||
},
|
||||
'deleteAllContent': function () {
|
||||
@ -111,10 +111,10 @@ db = {
|
||||
.then(function () {
|
||||
return when.resolve({ db: [] });
|
||||
}, function (error) {
|
||||
return when.reject({message: error.message || error});
|
||||
return when.reject(new errors.InternalServerError(error.message || error));
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to export data. (no rights)'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to export data. (no rights)'));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -12,34 +12,7 @@ var _ = require('lodash'),
|
||||
tags = require('./tags'),
|
||||
mail = require('./mail'),
|
||||
requestHandler,
|
||||
init,
|
||||
|
||||
errorTypes = {
|
||||
BadRequest: {
|
||||
code: 400
|
||||
},
|
||||
Unauthorized: {
|
||||
code: 401
|
||||
},
|
||||
NoPermission: {
|
||||
code: 403
|
||||
},
|
||||
NotFound: {
|
||||
code: 404
|
||||
},
|
||||
RequestEntityTooLarge: {
|
||||
code: 413
|
||||
},
|
||||
ValidationError: {
|
||||
code: 422
|
||||
},
|
||||
EmailError: {
|
||||
code: 500
|
||||
},
|
||||
InternalServerError: {
|
||||
code: 500
|
||||
}
|
||||
};
|
||||
init;
|
||||
|
||||
// ## Request Handlers
|
||||
|
||||
@ -169,14 +142,14 @@ requestHandler = function (apiMethod) {
|
||||
error = [].concat(error);
|
||||
}
|
||||
|
||||
_.each(error, function (erroritem) {
|
||||
_.each(error, function (errorItem) {
|
||||
var errorContent = {};
|
||||
|
||||
//TODO: add logic to set the correct status code
|
||||
errorCode = errorTypes[erroritem.type].code || 500;
|
||||
|
||||
errorContent['message'] = _.isString(erroritem) ? erroritem : (_.isObject(erroritem) ? erroritem.message : 'Unknown API Error');
|
||||
errorContent['type'] = erroritem.type || 'InternalServerError';
|
||||
errorCode = errorItem.code || 500;
|
||||
|
||||
errorContent['message'] = _.isString(errorItem) ? errorItem : (_.isObject(errorItem) ? errorItem.message : 'Unknown API Error');
|
||||
errorContent['type'] = errorItem.type || 'InternalServerError';
|
||||
errors.push(errorContent);
|
||||
});
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
var when = require("when"),
|
||||
config = require('../config'),
|
||||
var when = require("when"),
|
||||
config = require('../config'),
|
||||
errors = require('../errors'),
|
||||
mail;
|
||||
|
||||
|
||||
@ -22,7 +23,7 @@ mail = {
|
||||
return when.resolve({message: data.message });
|
||||
})
|
||||
.otherwise(function (error) {
|
||||
return when.reject({type: 'EmailError', message: error.message });
|
||||
return when.reject(new errors.EmailError(error.message));
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
var when = require('when'),
|
||||
_ = require('lodash'),
|
||||
errors = require('../errors'),
|
||||
|
||||
// Holds the persistent notifications
|
||||
notificationsStore = [],
|
||||
// Holds the last used id
|
||||
@ -22,11 +24,11 @@ notifications = {
|
||||
});
|
||||
|
||||
if (notification && !notification.dismissable) {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to dismiss this notification.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to dismiss this notification.'));
|
||||
}
|
||||
|
||||
if (!notification) {
|
||||
return when.reject({type: 'NoPermission', message: 'Notification does not exist.'});
|
||||
return when.reject(new errors.NotFoundError('Notification does not exist.'));
|
||||
}
|
||||
|
||||
notificationsStore = _.reject(notificationsStore, function (element) {
|
||||
|
@ -2,13 +2,14 @@ var when = require('when'),
|
||||
_ = require('lodash'),
|
||||
dataProvider = require('../models'),
|
||||
canThis = require('../permissions').canThis,
|
||||
errors = require('../errors'),
|
||||
|
||||
posts,
|
||||
allowedIncludes = ['created_by', 'updated_by', 'published_by', 'author', 'tags', 'fields'];
|
||||
allowedIncludes = ['created_by', 'updated_by', 'published_by', 'author', 'tags', 'fields'],
|
||||
posts;
|
||||
|
||||
function checkPostData(postData) {
|
||||
if (_.isEmpty(postData) || _.isEmpty(postData.posts) || _.isEmpty(postData.posts[0])) {
|
||||
return when.reject({type: 'BadRequest', message: 'No root key (\'posts\') provided.'});
|
||||
return when.reject(new errors.BadRequestError('No root key (\'posts\') provided.'));
|
||||
}
|
||||
return when.resolve(postData);
|
||||
}
|
||||
@ -69,7 +70,7 @@ posts = {
|
||||
return { posts: [ result.toJSON() ]};
|
||||
}
|
||||
|
||||
return when.reject({type: 'NotFound', message: 'Post not found.'});
|
||||
return when.reject(new errors.NotFoundError('Post not found.'));
|
||||
|
||||
});
|
||||
},
|
||||
@ -100,10 +101,10 @@ posts = {
|
||||
return { posts: [ post ]};
|
||||
}
|
||||
|
||||
return when.reject({type: 'NotFound', message: 'Post not found.'});
|
||||
return when.reject(new errors.NotFoundError('Post not found.'));
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to edit this post.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to edit this post.'));
|
||||
});
|
||||
},
|
||||
|
||||
@ -131,7 +132,7 @@ posts = {
|
||||
return { posts: [ post ]};
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to add posts.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to add posts.'));
|
||||
});
|
||||
},
|
||||
|
||||
@ -156,7 +157,7 @@ posts = {
|
||||
});
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to remove posts.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to remove posts.'));
|
||||
});
|
||||
},
|
||||
|
||||
@ -169,10 +170,10 @@ posts = {
|
||||
if (slug) {
|
||||
return slug;
|
||||
}
|
||||
return when.reject({type: 'InternalServerError', message: 'Could not generate slug'});
|
||||
return when.reject(new errors.InternalServerError('Could not generate slug'));
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission.'));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
config = require('../config'),
|
||||
canThis = require('../permissions').canThis,
|
||||
errors = require('../errors'),
|
||||
settings,
|
||||
settingsFilter,
|
||||
updateSettingsCache,
|
||||
@ -176,11 +177,11 @@ settings = {
|
||||
result = {};
|
||||
|
||||
if (!setting) {
|
||||
return when.reject({type: 'NotFound', message: 'Unable to find setting: ' + options.key});
|
||||
return when.reject(new errors.NotFoundError('Unable to find setting: ' + options.key));
|
||||
}
|
||||
|
||||
if (!self.internal && setting.type === 'core') {
|
||||
return when.reject({type: 'NoPermission', message: 'Attempted to access core setting on external request' });
|
||||
return when.reject(new errors.NoPermissionError('Attempted to access core setting on external request'));
|
||||
}
|
||||
|
||||
result[options.key] = setting;
|
||||
@ -200,11 +201,11 @@ settings = {
|
||||
var setting = settingsCache[settingInfo.key];
|
||||
|
||||
if (!setting) {
|
||||
return when.reject({type: 'NotFound', message: 'Unable to find setting: ' + settingInfo.key});
|
||||
return when.reject(new errors.NotFoundError('Unable to find setting: ' + settingInfo.key));
|
||||
}
|
||||
|
||||
if (!self.internal && setting.type === 'core') {
|
||||
return when.reject({type: 'NoPermission', message: 'Attempted to access core setting on external request' });
|
||||
return when.reject(new errors.NoPermissionError('Attempted to access core setting on external request'));
|
||||
}
|
||||
|
||||
return canThis(self).edit.setting(settingInfo.key);
|
||||
@ -239,14 +240,6 @@ settings = {
|
||||
return settingsResult(readResult, type);
|
||||
});
|
||||
}).catch(function (error) {
|
||||
// In case something goes wrong it is most likely because of an invalid key
|
||||
// or because of a badly formatted request.
|
||||
|
||||
// Check for actual javascript error, not api error
|
||||
if (error instanceof Error) {
|
||||
return when.reject({type: 'BadRequest', message: error.message});
|
||||
}
|
||||
|
||||
// Pass along API error
|
||||
return when.reject(error);
|
||||
});
|
||||
|
@ -3,13 +3,14 @@ var when = require('when'),
|
||||
dataProvider = require('../models'),
|
||||
settings = require('./settings'),
|
||||
canThis = require('../permissions').canThis,
|
||||
errors = require('../errors'),
|
||||
ONE_DAY = 86400000,
|
||||
users;
|
||||
|
||||
|
||||
function checkUserData(userData) {
|
||||
if (_.isEmpty(userData) || _.isEmpty(userData.users) || _.isEmpty(userData.users[0])) {
|
||||
return when.reject({code: 400, message: 'No root key (\'users\') provided.'});
|
||||
return when.reject(new errors.BadRequestError('No root key (\'users\') provided.'));
|
||||
}
|
||||
return when.resolve(userData);
|
||||
}
|
||||
@ -25,7 +26,7 @@ users = {
|
||||
return { users: result.toJSON() };
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to browse users.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to browse users.'));
|
||||
});
|
||||
},
|
||||
|
||||
@ -42,7 +43,7 @@ users = {
|
||||
return { users: [result.toJSON()] };
|
||||
}
|
||||
|
||||
return when.reject({type: 'NotFound', message: 'User not found.'});
|
||||
return when.reject(new errors.NotFoundError('User not found.'));
|
||||
});
|
||||
},
|
||||
|
||||
@ -58,10 +59,10 @@ users = {
|
||||
if (result) {
|
||||
return { users: [result.toJSON()]};
|
||||
}
|
||||
return when.reject({type: 'NotFound', message: 'User not found.'});
|
||||
return when.reject(new errors.NotFoundError('User not found.'));
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to edit this users.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to edit this users.'));
|
||||
});
|
||||
},
|
||||
|
||||
@ -84,7 +85,7 @@ users = {
|
||||
}
|
||||
});
|
||||
}, function () {
|
||||
return when.reject({type: 'NoPermission', message: 'You do not have permission to add a users.'});
|
||||
return when.reject(new errors.NoPermissionError('You do not have permission to add a users.'));
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
api = require('../api'),
|
||||
loader = require('./loader'),
|
||||
// Holds the available apps
|
||||
|
@ -4,7 +4,7 @@ var config = require('../config'),
|
||||
when = require('when'),
|
||||
api = require('../api'),
|
||||
mailer = require('../mail'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
storage = require('../storage'),
|
||||
updateCheck = require('../update-check'),
|
||||
|
||||
|
@ -15,6 +15,7 @@ var moment = require('moment'),
|
||||
config = require('../config'),
|
||||
filters = require('../../server/filters'),
|
||||
template = require('../helpers/template'),
|
||||
errors = require('../errors'),
|
||||
|
||||
frontendControllers,
|
||||
// Cache static post permalink regex
|
||||
@ -161,7 +162,7 @@ frontendControllers = {
|
||||
// If there are still no matches then return.
|
||||
if (staticPostPermalink.match(path) === false) {
|
||||
// Reject promise chain with type 'NotFound'
|
||||
return when.reject({type: 'NotFound'});
|
||||
return when.reject(new errors.NotFoundError());
|
||||
}
|
||||
|
||||
permalink = staticPostPermalink;
|
||||
@ -192,7 +193,7 @@ frontendControllers = {
|
||||
return res.redirect(config().paths.subdir + '/ghost/editor/' + post.id + '/');
|
||||
} else if (params.edit !== undefined) {
|
||||
// reject with type: 'NotFound'
|
||||
return when.reject({type: 'NotFound'});
|
||||
return when.reject(new errors.NotFoundError());
|
||||
}
|
||||
|
||||
setReqCtx(req, post);
|
||||
@ -254,7 +255,7 @@ frontendControllers = {
|
||||
// If we've thrown an error message
|
||||
// of type: 'NotFound' then we found
|
||||
// no path match.
|
||||
if (err.type === 'NotFound') {
|
||||
if (err.type === 'NotFoundError') {
|
||||
return next();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
errors = require('../../errorHandling'),
|
||||
errors = require('../../errors'),
|
||||
client = require('../../models/base').client,
|
||||
knex = require('../../models/base').knex,
|
||||
sequence = require('when/sequence'),
|
||||
|
@ -2,6 +2,7 @@ var schema = require('../schema').tables,
|
||||
_ = require('lodash'),
|
||||
validator = require('validator'),
|
||||
when = require('when'),
|
||||
errors = require('../../errors'),
|
||||
|
||||
validateSchema,
|
||||
validateSettings,
|
||||
@ -22,7 +23,7 @@ validator.extend('notContains', function (str, badString) {
|
||||
// form schema.js
|
||||
validateSchema = function (tableName, model) {
|
||||
var columns = _.keys(schema[tableName]),
|
||||
errors = [];
|
||||
validationErrors = [];
|
||||
|
||||
_.each(columns, function (columnKey) {
|
||||
var message = '';
|
||||
@ -31,7 +32,7 @@ validateSchema = function (tableName, model) {
|
||||
&& schema[tableName][columnKey].nullable !== true) {
|
||||
if (validator.isNull(model[columnKey]) || validator.empty(model[columnKey])) {
|
||||
message = 'Value in [' + tableName + '.' + columnKey + '] cannot be blank.';
|
||||
errors.push({type: 'ValidationError', property: tableName + '.' + columnKey, message: message});
|
||||
validationErrors.push(new errors.ValidationError(message, tableName + '.' + columnKey));
|
||||
}
|
||||
}
|
||||
// TODO: check if mandatory values should be enforced
|
||||
@ -41,27 +42,27 @@ validateSchema = function (tableName, model) {
|
||||
if (!validator.isLength(model[columnKey], 0, schema[tableName][columnKey].maxlength)) {
|
||||
message = 'Value in [' + tableName + '.' + columnKey + '] exceeds maximum length of '
|
||||
+ schema[tableName][columnKey].maxlength + ' characters.';
|
||||
errors.push({type: 'ValidationError', property: tableName + '.' + columnKey, message: message});
|
||||
validationErrors.push(new errors.ValidationError(message, tableName + '.' + columnKey));
|
||||
}
|
||||
}
|
||||
|
||||
//check validations objects
|
||||
if (schema[tableName][columnKey].hasOwnProperty('validations')) {
|
||||
errors.concat(validate(model[columnKey], columnKey, schema[tableName][columnKey].validations));
|
||||
validationErrors.concat(validate(model[columnKey], columnKey, schema[tableName][columnKey].validations));
|
||||
}
|
||||
|
||||
//check type
|
||||
if (schema[tableName][columnKey].hasOwnProperty('type')) {
|
||||
if (schema[tableName][columnKey].type === 'integer' && !validator.isInt(model[columnKey])) {
|
||||
message = 'Value in [' + tableName + '.' + columnKey + '] is no valid integer.';
|
||||
errors.push({type: 'ValidationError', property: tableName + '.' + columnKey, message: message});
|
||||
validationErrors.push(new errors.ValidationError(message, tableName + '.' + columnKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (errors.length !== 0) {
|
||||
return when.reject(errors);
|
||||
if (validationErrors.length !== 0) {
|
||||
return when.reject(validationErrors);
|
||||
}
|
||||
};
|
||||
|
||||
@ -95,7 +96,7 @@ validateSettings = function (defaultSettings, model) {
|
||||
//
|
||||
// available validators: https://github.com/chriso/validator.js#validators
|
||||
validate = function (value, key, validations) {
|
||||
var errors = [];
|
||||
var validationErrors = [];
|
||||
_.each(validations, function (validationOptions, validationName) {
|
||||
var goodResult = true;
|
||||
|
||||
@ -110,14 +111,14 @@ validate = function (value, key, validations) {
|
||||
|
||||
// equivalent of validator.isSomething(option1, option2)
|
||||
if (validator[validationName].apply(validator, validationOptions) !== goodResult) {
|
||||
errors.push({type: 'ValidationError', property: key, message: 'Settings validation (' + validationName + ') failed for ' + key});
|
||||
validationErrors.push(new errors.ValidationError('Settings validation (' + validationName + ') failed for ' + key, key));
|
||||
}
|
||||
|
||||
validationOptions.shift();
|
||||
}, this);
|
||||
|
||||
if (errors.length !== 0) {
|
||||
return when.reject(errors);
|
||||
if (validationErrors.length !== 0) {
|
||||
return when.reject(validationErrors);
|
||||
}
|
||||
};
|
||||
|
||||
|
15
core/server/errors/badrequesterror.js
Normal file
15
core/server/errors/badrequesterror.js
Normal file
@ -0,0 +1,15 @@
|
||||
// # Bad request error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function BadRequestError(message) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 400;
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
BadRequestError.prototype = Object.create(Error.prototype);
|
||||
BadRequestError.prototype.name = "BadRequestError";
|
||||
|
||||
|
||||
module.exports = BadRequestError;
|
15
core/server/errors/emailerror.js
Normal file
15
core/server/errors/emailerror.js
Normal file
@ -0,0 +1,15 @@
|
||||
// # Email error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function EmailError(message) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 500;
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
EmailError.prototype = Object.create(Error.prototype);
|
||||
EmailError.prototype.name = "EmailError";
|
||||
|
||||
|
||||
module.exports = EmailError;
|
@ -1,10 +1,17 @@
|
||||
/*jslint regexp: true */
|
||||
var _ = require('lodash'),
|
||||
colors = require('colors'),
|
||||
config = require('./config'),
|
||||
path = require('path'),
|
||||
when = require('when'),
|
||||
hbs = require('express-hbs'),
|
||||
var _ = require('lodash'),
|
||||
colors = require('colors'),
|
||||
config = require('../config'),
|
||||
path = require('path'),
|
||||
when = require('when'),
|
||||
hbs = require('express-hbs'),
|
||||
NotFoundError = require('./notfounderror'),
|
||||
BadRequestError = require('./badrequesterror'),
|
||||
InternalServerError = require('./internalservererror'),
|
||||
NoPermissionError = require('./nopermissionerror'),
|
||||
RequestEntityTooLargeError = require('./requesttoolargeerror'),
|
||||
UnauthorizedError = require('./unauthorizederror'),
|
||||
ValidationError = require('./validationerror'),
|
||||
errors,
|
||||
|
||||
// Paths for views
|
||||
@ -242,4 +249,11 @@ _.each([
|
||||
errors[funcName] = errors[funcName].bind(errors);
|
||||
});
|
||||
|
||||
module.exports = errors;
|
||||
module.exports = errors;
|
||||
module.exports.NotFoundError = NotFoundError;
|
||||
module.exports.BadRequestError = BadRequestError;
|
||||
module.exports.InternalServerError = InternalServerError;
|
||||
module.exports.NoPermissionError = NoPermissionError;
|
||||
module.exports.UnauthorizedError = UnauthorizedError;
|
||||
module.exports.ValidationError = ValidationError;
|
||||
module.exports.RequestEntityTooLargeError = RequestEntityTooLargeError;
|
15
core/server/errors/internalservererror.js
Normal file
15
core/server/errors/internalservererror.js
Normal file
@ -0,0 +1,15 @@
|
||||
// # Internal Server Error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function InternalServerError(message) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 500;
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
InternalServerError.prototype = Object.create(Error.prototype);
|
||||
InternalServerError.prototype.name = "InternalServerError";
|
||||
|
||||
|
||||
module.exports = InternalServerError;
|
15
core/server/errors/nopermissionerror.js
Normal file
15
core/server/errors/nopermissionerror.js
Normal file
@ -0,0 +1,15 @@
|
||||
// # No Permission Error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function NoPermissionError(message) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 403;
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
NoPermissionError.prototype = Object.create(Error.prototype);
|
||||
NoPermissionError.prototype.name = "NoPermissionError";
|
||||
|
||||
|
||||
module.exports = NoPermissionError;
|
15
core/server/errors/notfounderror.js
Normal file
15
core/server/errors/notfounderror.js
Normal file
@ -0,0 +1,15 @@
|
||||
// # Not found error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function NotFoundError(message) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 404;
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
NotFoundError.prototype = Object.create(Error.prototype);
|
||||
NotFoundError.prototype.name = "NotFoundError";
|
||||
|
||||
|
||||
module.exports = NotFoundError;
|
15
core/server/errors/requesttoolargeerror.js
Normal file
15
core/server/errors/requesttoolargeerror.js
Normal file
@ -0,0 +1,15 @@
|
||||
// # Request Entity Too Large Error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function RequestEntityTooLargeError(message) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 413;
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
RequestEntityTooLargeError.prototype = Object.create(Error.prototype);
|
||||
RequestEntityTooLargeError.prototype.name = "RequestEntityTooLargeError";
|
||||
|
||||
|
||||
module.exports = RequestEntityTooLargeError;
|
15
core/server/errors/unauthorizederror.js
Normal file
15
core/server/errors/unauthorizederror.js
Normal file
@ -0,0 +1,15 @@
|
||||
// # Unauthorized error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function UnauthorizedError(message) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 404;
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
UnauthorizedError.prototype = Object.create(Error.prototype);
|
||||
UnauthorizedError.prototype.name = "UnauthorizedError";
|
||||
|
||||
|
||||
module.exports = UnauthorizedError;
|
22
core/server/errors/validationerror.js
Normal file
22
core/server/errors/validationerror.js
Normal file
@ -0,0 +1,22 @@
|
||||
// # Validation Error
|
||||
// Custom error class with status code and type prefilled.
|
||||
|
||||
function ValidationError(message) {
|
||||
return new ValidationError(message, null);
|
||||
}
|
||||
|
||||
function ValidationError(message, offendingProperty) {
|
||||
this.message = message;
|
||||
this.stack = new Error().stack;
|
||||
this.code = 422;
|
||||
if (offendingProperty) {
|
||||
this.property = offendingProperty;
|
||||
}
|
||||
this.type = this.name;
|
||||
}
|
||||
|
||||
ValidationError.prototype = Object.create(Error.prototype);
|
||||
ValidationError.prototype.name = "ValidationError";
|
||||
|
||||
|
||||
module.exports = ValidationError;
|
@ -7,7 +7,7 @@ var downsize = require('downsize'),
|
||||
|
||||
api = require('../api'),
|
||||
config = require('../config'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
filters = require('../filters'),
|
||||
template = require('./template'),
|
||||
schema = require('../data/schema').checks,
|
||||
|
@ -1,6 +1,6 @@
|
||||
var templates = {},
|
||||
hbs = require('express-hbs'),
|
||||
errors = require('../errorHandling');
|
||||
errors = require('../errors');
|
||||
|
||||
// ## Template utils
|
||||
|
||||
|
@ -12,7 +12,7 @@ var crypto = require('crypto'),
|
||||
|
||||
api = require('./api'),
|
||||
config = require('./config'),
|
||||
errors = require('./errorHandling'),
|
||||
errors = require('./errors'),
|
||||
helpers = require('./helpers'),
|
||||
mailer = require('./mail'),
|
||||
middleware = require('./middleware'),
|
||||
|
@ -2,7 +2,8 @@ var BusBoy = require('busboy'),
|
||||
fs = require('fs-extra'),
|
||||
path = require('path'),
|
||||
os = require('os'),
|
||||
crypto = require('crypto');
|
||||
crypto = require('crypto'),
|
||||
errors = require('../errors');
|
||||
|
||||
// ### ghostBusboy
|
||||
// Process multipart file streams
|
||||
@ -55,7 +56,7 @@ function ghostBusBoy(req, res, next) {
|
||||
|
||||
busboy.on('limit', function () {
|
||||
hasError = true;
|
||||
res.send(413, {type: 'RequestEntityTooLarge', message: 'File size limit breached.'});
|
||||
res.send(413, new errors.RequestEntityTooLargeError('File size limit breached.'));
|
||||
});
|
||||
|
||||
busboy.on('error', function (error) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
var api = require('../api'),
|
||||
BSStore = require('../bookshelf-session'),
|
||||
config = require('../config'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
express = require('express'),
|
||||
fs = require('fs'),
|
||||
hbs = require('express-hbs'),
|
||||
|
@ -2,7 +2,7 @@
|
||||
var _ = require('lodash'),
|
||||
uuid = require('node-uuid'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
Showdown = require('showdown'),
|
||||
ghostgfm = require('../../shared/lib/showdown/extensions/ghostgfm'),
|
||||
converter = new Showdown.converter({extensions: [ghostgfm]}),
|
||||
|
@ -2,7 +2,7 @@ var Settings,
|
||||
ghostBookshelf = require('./base'),
|
||||
uuid = require('node-uuid'),
|
||||
_ = require('lodash'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
when = require('when'),
|
||||
validation = require('../data/validation'),
|
||||
|
||||
@ -100,7 +100,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||
// Accept an array of models as input
|
||||
if (item.toJSON) { item = item.toJSON(); }
|
||||
if (!(_.isString(item.key) && item.key.length > 0)) {
|
||||
return when.reject({type: 'ValidationError', message: 'Setting key cannot be empty.'});
|
||||
return when.reject(new errors.ValidationError('Setting key cannot be empty.'));
|
||||
}
|
||||
|
||||
item = self.filterData(item);
|
||||
@ -111,7 +111,7 @@ Settings = ghostBookshelf.Model.extend({
|
||||
return setting.save({value: item.value}, options);
|
||||
}
|
||||
|
||||
return when.reject({type: 'NotFound', message: 'Unable to find setting to update: ' + item.key});
|
||||
return when.reject(new errors.NotFoundError('Unable to find setting to update: ' + item.key));
|
||||
|
||||
}, errors.logAndThrowError);
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
var _ = require('lodash'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
nodefn = require('when/node/function'),
|
||||
bcrypt = require('bcryptjs'),
|
||||
Posts = require('./post').Posts,
|
||||
|
@ -1,6 +1,6 @@
|
||||
var _ = require('lodash'),
|
||||
Models = require('../models'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
User = Models.User,
|
||||
App = Models.App;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
var errors = require('../errorHandling'),
|
||||
var errors = require('../errors'),
|
||||
storage;
|
||||
|
||||
function get_storage() {
|
||||
|
@ -7,7 +7,7 @@ var _ = require('lodash'),
|
||||
nodefn = require('when/node/function'),
|
||||
path = require('path'),
|
||||
when = require('when'),
|
||||
errors = require('../errorHandling'),
|
||||
errors = require('../errors'),
|
||||
config = require('../config'),
|
||||
baseStore = require('./base'),
|
||||
|
||||
|
@ -30,7 +30,7 @@ var crypto = require('crypto'),
|
||||
|
||||
api = require('./api'),
|
||||
config = require('./config'),
|
||||
errors = require('./errorHandling'),
|
||||
errors = require('./errors'),
|
||||
packageInfo = require('../../package.json'),
|
||||
|
||||
allowedCheckEnvironments = ['development', 'production'],
|
||||
|
@ -1,6 +1,6 @@
|
||||
var _ = require('lodash'),
|
||||
config = require('./config'),
|
||||
errors = require('./errorHandling'),
|
||||
errors = require('./errors'),
|
||||
http = require('http'),
|
||||
xml = require('xml'),
|
||||
pingList;
|
||||
|
@ -55,7 +55,7 @@ describe('DB API', function () {
|
||||
done();
|
||||
});
|
||||
}).catch(function (error) {
|
||||
done('error', error);
|
||||
done(error);
|
||||
});
|
||||
});
|
||||
|
||||
@ -65,17 +65,17 @@ describe('DB API', function () {
|
||||
}).then(function (){
|
||||
done(new Error("Delete all content is not denied for editor."));
|
||||
}, function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
return dbAPI.deleteAllContent.call({user: 3});
|
||||
}).then(function (){
|
||||
done(new Error("Delete all content is not denied for author."));
|
||||
}, function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
return dbAPI.deleteAllContent();
|
||||
}).then(function (){
|
||||
done(new Error("Delete all content is not denied without authentication."));
|
||||
}).catch(function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -86,17 +86,17 @@ describe('DB API', function () {
|
||||
}).then(function (){
|
||||
done(new Error("Export content is not denied for editor."));
|
||||
}, function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
return dbAPI.exportContent.call({user: 3});
|
||||
}).then(function (){
|
||||
done(new Error("Export content is not denied for author."));
|
||||
}, function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
return dbAPI.exportContent();
|
||||
}).then(function (){
|
||||
done(new Error("Export content is not denied without authentication."));
|
||||
}).catch(function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -107,17 +107,17 @@ describe('DB API', function () {
|
||||
}).then(function (result){
|
||||
done(new Error("Import content is not denied for editor."));
|
||||
}, function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
return dbAPI.importContent.call({user: 3});
|
||||
}).then(function (result){
|
||||
done(new Error("Import content is not denied for author."));
|
||||
}, function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
return dbAPI.importContent();
|
||||
}).then(function (result){
|
||||
done(new Error("Import content is not denied without authentication."));
|
||||
}).catch(function (error) {
|
||||
error.type.should.eql('NoPermission');
|
||||
error.type.should.eql('NoPermissionError');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*globals describe, it, before, beforeEach, afterEach */
|
||||
var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
errors = require('../../../server/errorHandling'),
|
||||
errors = require('../../../server/errors'),
|
||||
|
||||
// Stuff we are testing
|
||||
Models = require('../../../server/models');
|
||||
|
@ -3,7 +3,7 @@ var testUtils = require('../../utils'),
|
||||
should = require('should'),
|
||||
when = require('when'),
|
||||
_ = require('lodash'),
|
||||
errors = require('../../../server/errorHandling'),
|
||||
errors = require('../../../server/errors'),
|
||||
sinon = require('sinon'),
|
||||
uuid = require('node-uuid'),
|
||||
|
||||
|
@ -8,7 +8,7 @@ var testUtils = require('../utils'),
|
||||
|
||||
// Stuff we are testing
|
||||
colors = require('colors'),
|
||||
errors = rewire('../../server/errorHandling'),
|
||||
errors = rewire('../../server/errors'),
|
||||
// storing current environment
|
||||
currentEnv = process.env.NODE_ENV;
|
||||
|
||||
|
@ -4,7 +4,7 @@ var testUtils = require('../utils'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
_ = require("lodash"),
|
||||
errors = require('../../server/errorHandling'),
|
||||
errors = require('../../server/errors'),
|
||||
|
||||
// Stuff we are testing
|
||||
migration = require('../../server/data/migration'),
|
||||
|
@ -5,7 +5,7 @@ var testUtils = require('../utils'),
|
||||
when = require('when'),
|
||||
assert = require('assert'),
|
||||
_ = require("lodash"),
|
||||
errors = require('../../server/errorHandling'),
|
||||
errors = require('../../server/errors'),
|
||||
|
||||
// Stuff we are testing
|
||||
knex = require("../../server/models/base").knex,
|
||||
|
@ -4,7 +4,7 @@ var testUtils = require('../utils'),
|
||||
sinon = require('sinon'),
|
||||
when = require('when'),
|
||||
_ = require("lodash"),
|
||||
errors = require('../../server/errorHandling'),
|
||||
errors = require('../../server/errors'),
|
||||
|
||||
// Stuff we are testing
|
||||
permissions = require('../../server/permissions'),
|
||||
|
Loading…
Reference in New Issue
Block a user