Switch to @tryghost/errors from ignition errors package (#13807)

refs: TryGhost/Toolbox#147

* Replaces all references to isIgnitionError with isGhostError
* Switches use of GhostError to InternalServerError - as GhostError is no longer public
There are places where InternalServerError is not the valid error, and new errors should be added to the @tryghost/errors package to ensure that we can use semantically correct errors in those cases.
This commit is contained in:
Sam Lord 2021-12-01 10:22:01 +00:00 committed by GitHub
parent 8364ef80fe
commit 2887e416da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 102 additions and 97 deletions

View File

@ -404,8 +404,8 @@ async function bootGhost({backend = true, frontend = true} = {}) {
// Ensure the error we have is an ignition error // Ensure the error we have is an ignition error
let serverStartError = error; let serverStartError = error;
if (!errors.utils.isIgnitionError(serverStartError)) { if (!errors.utils.isGhostError(serverStartError)) {
serverStartError = new errors.GhostError({message: serverStartError.message, err: serverStartError}); serverStartError = new errors.InternalServerError({message: serverStartError.message, err: serverStartError});
} }
logging.error(serverStartError); logging.error(serverStartError);

View File

@ -143,7 +143,7 @@ function getAmperizeHTML(html, post) {
if (err) { if (err) {
if (err.src) { if (err.src) {
// This is a valid 500 GhostError because it means the amperize parser is unable to handle some Ghost HTML. // This is a valid 500 GhostError because it means the amperize parser is unable to handle some Ghost HTML.
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
message: `AMP HTML couldn't be parsed: ${err.src}`, message: `AMP HTML couldn't be parsed: ${err.src}`,
code: 'AMP_PARSER_ERROR', code: 'AMP_PARSER_ERROR',
err: err, err: err,
@ -151,7 +151,7 @@ function getAmperizeHTML(html, post) {
help: 'Please share this error on GitHub or https://forum.ghost.org' help: 'Please share this error on GitHub or https://forum.ghost.org'
})); }));
} else { } else {
logging.error(new errors.GhostError({err, code: 'AMP_PARSER_ERROR'})); logging.error(new errors.InternalServerError({err, code: 'AMP_PARSER_ERROR'}));
} }
// save it in cache to prevent multiple calls to Amperize until // save it in cache to prevent multiple calls to Amperize until

View File

@ -24,7 +24,7 @@ let checkSubdir = function checkSubdir() {
paths = urlUtils.getSubdir().split('/'); paths = urlUtils.getSubdir().split('/');
if (paths.pop() === PRIVATE_KEYWORD) { if (paths.pop() === PRIVATE_KEYWORD) {
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
message: tpl(messages.urlCannotContainPrivateSubdir.error), message: tpl(messages.urlCannotContainPrivateSubdir.error),
context: tpl(messages.urlCannotContainPrivateSubdir.description), context: tpl(messages.urlCannotContainPrivateSubdir.description),
help: tpl(messages.urlCannotContainPrivateSubdir.help) help: tpl(messages.urlCannotContainPrivateSubdir.help)

View File

@ -18,7 +18,7 @@ module.exports = {
return Promise.map(appsToLoad, appName => loader.activateAppByName(appName)) return Promise.map(appsToLoad, appName => loader.activateAppByName(appName))
.catch(function (err) { .catch(function (err) {
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
err: err, err: err,
context: tpl(messages.appWillNotBeLoadedError), context: tpl(messages.appWillNotBeLoadedError),
help: tpl(messages.appWillNotBeLoadedHelp) help: tpl(messages.appWillNotBeLoadedHelp)

View File

@ -17,7 +17,7 @@ function asyncHelperWrapper(hbsInstance, name, fn) {
Promise.resolve(fn.call(this, context, options)).then(function asyncHelperSuccess(result) { Promise.resolve(fn.call(this, context, options)).then(function asyncHelperSuccess(result) {
cb(result); cb(result);
}).catch(function asyncHelperError(err) { }).catch(function asyncHelperError(err) {
const wrappedErr = err instanceof errors.GhostError ? err : new errors.IncorrectUsageError({ const wrappedErr = errors.utils.isGhostError(err) ? err : new errors.IncorrectUsageError({
err: err, err: err,
context: 'registerAsyncThemeHelper: ' + name, context: 'registerAsyncThemeHelper: ' + name,
errorDetails: { errorDetails: {

View File

@ -1,6 +1,6 @@
const _ = require('lodash'); const _ = require('lodash');
const path = require('path'); const path = require('path');
const {GhostError} = require('@tryghost/errors'); const {NoContentError} = require('@tryghost/errors');
const imageTransform = require('@tryghost/image-transform'); const imageTransform = require('@tryghost/image-transform');
const storage = require('../../../server/adapters/storage'); const storage = require('../../../server/adapters/storage');
const activeTheme = require('../../services/theme-engine/active'); const activeTheme = require('../../services/theme-engine/active');
@ -102,10 +102,7 @@ module.exports = function (req, res, next) {
}) })
.then((originalImageBuffer) => { .then((originalImageBuffer) => {
if (originalImageBuffer.length <= 0) { if (originalImageBuffer.length <= 0) {
throw new GhostError({ throw new NoContentError();
errorType: 'NoContentError',
statusCode: 204
});
} }
return imageTransform.resizeFromBuffer(originalImageBuffer, imageDimensionConfig); return imageTransform.resizeFromBuffer(originalImageBuffer, imageDimensionConfig);
}) })

View File

@ -307,7 +307,7 @@ SchedulingDefault.prototype._pingUrl = function (object) {
this._pingUrl(object); this._pingUrl(object);
}, this.retryTimeoutInMs); }, this.retryTimeoutInMs);
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
err, err,
context: 'Retrying...', context: 'Retrying...',
level: 'normal' level: 'normal'
@ -316,7 +316,7 @@ SchedulingDefault.prototype._pingUrl = function (object) {
return; return;
} }
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
err, err,
level: 'critical' level: 'critical'
})); }));

View File

@ -147,7 +147,7 @@ class LocalStorageBase extends StorageBase {
return next(new errors.NoPermissionError({err: err})); return next(new errors.NoPermissionError({err: err}));
} }
return next(new errors.GhostError({err: err})); return next(new errors.InternalServerError({err: err}));
} }
next(); next();
@ -196,7 +196,7 @@ class LocalStorageBase extends StorageBase {
return reject(new errors.NoPermissionError({err: err})); return reject(new errors.NoPermissionError({err: err}));
} }
return reject(new errors.GhostError({ return reject(new errors.InternalServerError({
err: err, err: err,
message: tpl(this.errorMessages.cannotRead, {file: options.path}) message: tpl(this.errorMessages.cannotRead, {file: options.path})
})); }));

View File

@ -62,7 +62,7 @@ module.exports = {
return Promise.resolve() return Promise.resolve()
.then(() => exporter.doExport({include: frame.options.withRelated})) .then(() => exporter.doExport({include: frame.options.withRelated}))
.catch((err) => { .catch((err) => {
return Promise.reject(new errors.GhostError({err: err})); return Promise.reject(new errors.InternalServerError({err: err}));
}); });
} }
}, },
@ -124,7 +124,7 @@ module.exports = {
}, {concurrency: 100}); }, {concurrency: 100});
}) })
.catch((err) => { .catch((err) => {
throw new errors.GhostError({ throw new errors.InternalServerError({
err: err err: err
}); });
}); });

View File

@ -42,7 +42,7 @@ const session = {
}); });
}); });
}).catch(async (err) => { }).catch(async (err) => {
if (!errors.utils.isIgnitionError(err)) { if (!errors.utils.isGhostError(err)) {
throw new errors.UnauthorizedError({ throw new errors.UnauthorizedError({
message: tpl(messages.accessDenied), message: tpl(messages.accessDenied),
err err

View File

@ -43,7 +43,7 @@ module.exports = {
return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'}) return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'})
.then((slug) => { .then((slug) => {
if (!slug) { if (!slug) {
return Promise.reject(new errors.GhostError({ return Promise.reject(new errors.InternalServerError({
message: tpl(messages.couldNotGenerateSlug) message: tpl(messages.couldNotGenerateSlug)
})); }));
} }

View File

@ -66,11 +66,11 @@ const nonePublicAuth = (apiConfig, frame) => {
return Promise.reject(err); return Promise.reject(err);
} }
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
return Promise.reject(err); return Promise.reject(err);
} }
return Promise.reject(new errors.GhostError({ return Promise.reject(new errors.InternalServerError({
err: err err: err
})); }));
}); });

View File

@ -51,7 +51,7 @@ module.exports = {
return Promise.resolve() return Promise.resolve()
.then(() => exporter.doExport({include: frame.options.withRelated})) .then(() => exporter.doExport({include: frame.options.withRelated}))
.catch((err) => { .catch((err) => {
return Promise.reject(new errors.GhostError({err: err})); return Promise.reject(new errors.InternalServerError({err: err}));
}); });
} }
}, },
@ -107,7 +107,7 @@ module.exports = {
}, {concurrency: 100}); }, {concurrency: 100});
}) })
.catch((err) => { .catch((err) => {
throw new errors.GhostError({ throw new errors.InternalServerError({
err: err err: err
}); });
}); });

View File

@ -42,7 +42,7 @@ const session = {
}); });
}); });
}).catch(async (err) => { }).catch(async (err) => {
if (!errors.utils.isIgnitionError(err)) { if (!errors.utils.isGhostError(err)) {
throw new errors.UnauthorizedError({ throw new errors.UnauthorizedError({
message: tpl(messages.authAccessDenied), message: tpl(messages.authAccessDenied),
err err

View File

@ -40,7 +40,7 @@ module.exports = {
return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'}) return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'})
.then((slug) => { .then((slug) => {
if (!slug) { if (!slug) {
return Promise.reject(new errors.GhostError({ return Promise.reject(new errors.InternalServerError({
message: tpl(messages.couldNotGenerateSlug) message: tpl(messages.couldNotGenerateSlug)
})); }));
} }

View File

@ -62,11 +62,11 @@ const nonePublicAuth = (apiConfig, frame) => {
return Promise.reject(err); return Promise.reject(err);
} }
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
return Promise.reject(err); return Promise.reject(err);
} }
return Promise.reject(new errors.GhostError({ return Promise.reject(new errors.InternalServerError({
err: err err: err
})); }));
}); });

View File

@ -62,7 +62,7 @@ module.exports = {
return Promise.resolve() return Promise.resolve()
.then(() => exporter.doExport({include: frame.options.withRelated})) .then(() => exporter.doExport({include: frame.options.withRelated}))
.catch((err) => { .catch((err) => {
return Promise.reject(new errors.GhostError({err: err})); return Promise.reject(new errors.InternalServerError({err: err}));
}); });
} }
}, },
@ -118,7 +118,7 @@ module.exports = {
}, {concurrency: 100}); }, {concurrency: 100});
}) })
.catch((err) => { .catch((err) => {
throw new errors.GhostError({ throw new errors.InternalServerError({
err: err err: err
}); });
}); });

View File

@ -42,7 +42,7 @@ const session = {
}); });
}); });
}).catch(async (err) => { }).catch(async (err) => {
if (!errors.utils.isIgnitionError(err)) { if (!errors.utils.isGhostError(err)) {
throw new errors.UnauthorizedError({ throw new errors.UnauthorizedError({
message: tpl(messages.accessDenied), message: tpl(messages.accessDenied),
err err

View File

@ -39,7 +39,7 @@ module.exports = {
return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'}) return models.Base.Model.generateSlug(allowedTypes[frame.options.type], frame.data.name, {status: 'all'})
.then((slug) => { .then((slug) => {
if (!slug) { if (!slug) {
return Promise.reject(new errors.GhostError({message: tpl(messages.couldNotGenerateSlug)})); return Promise.reject(new errors.InternalServerError({message: tpl(messages.couldNotGenerateSlug)}));
} }
return slug; return slug;
}); });

View File

@ -66,11 +66,11 @@ const nonePublicAuth = (apiConfig, frame) => {
return Promise.reject(err); return Promise.reject(err);
} }
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
return Promise.reject(err); return Promise.reject(err);
} }
return Promise.reject(new errors.GhostError({ return Promise.reject(new errors.InternalServerError({
err: err err: err
})); }));
}); });

View File

@ -59,8 +59,8 @@ class DatabaseStateManager {
// CASE: database connection errors, unknown cases // CASE: database connection errors, unknown cases
let errorToThrow = error; let errorToThrow = error;
if (!errors.utils.isIgnitionError(errorToThrow)) { if (!errors.utils.isGhostError(errorToThrow)) {
errorToThrow = new errors.GhostError({message: errorToThrow.message, err: errorToThrow}); errorToThrow = new errors.InternalServerError({message: errorToThrow.message, err: errorToThrow});
} }
throw errorToThrow; throw errorToThrow;
@ -94,8 +94,8 @@ class DatabaseStateManager {
} }
} catch (error) { } catch (error) {
let errorToThrow = error; let errorToThrow = error;
if (!errors.utils.isIgnitionError(error)) { if (!errors.utils.isGhostError(error)) {
errorToThrow = new errors.GhostError({message: errorToThrow.message, err: errorToThrow}); errorToThrow = new errors.InternalServerError({message: errorToThrow.message, err: errorToThrow});
} }
throw errorToThrow; throw errorToThrow;

View File

@ -26,7 +26,7 @@ const exportFileName = async function exportFileName(options) {
return title + 'ghost.' + datetime + '.json'; return title + 'ghost.' + datetime + '.json';
} catch (err) { } catch (err) {
logging.error(new errors.GhostError({err: err})); logging.error(new errors.InternalServerError({err: err}));
return 'ghost.' + datetime + '.json'; return 'ghost.' + datetime + '.json';
} }
}; };

View File

@ -30,7 +30,7 @@ JSONHandler = {
// if importData follows JSON-API format `{ db: [exportedData] }` // if importData follows JSON-API format `{ db: [exportedData] }`
if (_.keys(importData).length === 1) { if (_.keys(importData).length === 1) {
if (!importData.db || !Array.isArray(importData.db)) { if (!importData.db || !Array.isArray(importData.db)) {
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.invalidJsonFormat) message: tpl(messages.invalidJsonFormat)
}); });
} }

View File

@ -121,7 +121,7 @@ class ImportManager {
fs.remove(self.fileToDelete, function (err) { fs.remove(self.fileToDelete, function (err) {
if (err) { if (err) {
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
err: err, err: err,
context: tpl(messages.couldNotCleanUpFile.error), context: tpl(messages.couldNotCleanUpFile.error),
help: tpl(messages.couldNotCleanUpFile.context) help: tpl(messages.couldNotCleanUpFile.context)

View File

@ -145,7 +145,7 @@ class Base {
}); });
} }
} else { } else {
if (!errors.utils.isIgnitionError(err)) { if (!errors.utils.isGhostError(err)) {
err = new errors.DataImportError({ err = new errors.DataImportError({
message: err.message, message: err.message,
context: JSON.stringify(obj), context: JSON.stringify(obj),

View File

@ -143,7 +143,7 @@ function addPermissionToRole(config) {
}).first(); }).first();
if (!permission) { if (!permission) {
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.permissionRoleActionError, { message: tpl(messages.permissionRoleActionError, {
action: 'add', action: 'add',
permission: config.permission, permission: config.permission,
@ -158,7 +158,7 @@ function addPermissionToRole(config) {
}).first(); }).first();
if (!role) { if (!role) {
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.permissionRoleActionError, { message: tpl(messages.permissionRoleActionError, {
action: 'add', action: 'add',
permission: config.permission, permission: config.permission,

View File

@ -44,7 +44,7 @@ module.exports = createTransactionalMigration(
return amount * 30; return amount * 30;
} }
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.unknownSubscriptionIntervalError , { message: tpl(messages.unknownSubscriptionIntervalError , {
interval interval
}) })

View File

@ -139,7 +139,7 @@ async function hasForeignSQLite({fromTable, fromColumn, toTable, toColumn, trans
const client = knex.client.config.client; const client = knex.client.config.client;
if (client !== 'sqlite3') { if (client !== 'sqlite3') {
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.hasForeignSQLite3) message: tpl(messages.hasForeignSQLite3)
}); });
} }
@ -265,7 +265,7 @@ async function hasPrimaryKeySQLite(tableName, transaction) {
const client = knex.client.config.client; const client = knex.client.config.client;
if (client !== 'sqlite3') { if (client !== 'sqlite3') {
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.hasPrimaryKeySQLiteError) message: tpl(messages.hasPrimaryKeySQLiteError)
}); });
} }

View File

@ -107,13 +107,13 @@ class GhostServer {
let ghostError; let ghostError;
if (error.code === 'EADDRINUSE') { if (error.code === 'EADDRINUSE') {
ghostError = new errors.GhostError({ ghostError = new errors.InternalServerError({
message: tpl(messages.addressInUse.error), message: tpl(messages.addressInUse.error),
context: tpl(messages.addressInUse.context, {port: config.get('server').port}), context: tpl(messages.addressInUse.context, {port: config.get('server').port}),
help: tpl(messages.addressInUse.help) help: tpl(messages.addressInUse.help)
}); });
} else { } else {
ghostError = new errors.GhostError({ ghostError = new errors.InternalServerError({
message: tpl(messages.otherError.error, {errorNumber: error.errno}), message: tpl(messages.otherError.error, {errorNumber: error.errno}),
context: tpl(messages.otherError.context), context: tpl(messages.otherError.context),
help: tpl(messages.otherError.help) help: tpl(messages.otherError.help)

View File

@ -177,7 +177,7 @@ class ImageSize {
context: err.url || imagePath context: err.url || imagePath
})); }));
}).catch(function (err) { }).catch(function (err) {
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
return Promise.reject(err); return Promise.reject(err);
} }
@ -241,7 +241,7 @@ class ImageSize {
} }
})); }));
}).catch((err) => { }).catch((err) => {
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
return Promise.reject(err); return Promise.reject(err);
} }

View File

@ -69,13 +69,13 @@ events.on('settings.timezone.edited', function (settingModel, options) {
try { try {
await models.Post.edit(post.toJSON(), _.merge({id: post.id}, options)); await models.Post.edit(post.toJSON(), _.merge({id: post.id}, options));
} catch (err) { } catch (err) {
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
err err
})); }));
} }
}); });
} catch (err) { } catch (err) {
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
err: err, err: err,
level: 'critical' level: 'critical'
})); }));

View File

@ -324,7 +324,7 @@ module.exports.extendModel = function extendModel(Post, Posts, ghostBookshelf) {
.then(() => response); .then(() => response);
}) })
.catch((err) => { .catch((err) => {
throw new errors.GhostError({err: err}); throw new errors.InternalServerError({err: err});
}); });
}); });

View File

@ -148,7 +148,7 @@ function doReset(options, tokenParts, settingsAPI) {
return Promise.reject(err); return Promise.reject(err);
}) })
.catch((err) => { .catch((err) => {
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
return Promise.reject(err); return Promise.reject(err);
} }
return Promise.reject(new errors.UnauthorizedError({err: err})); return Promise.reject(new errors.UnauthorizedError({err: err}));

View File

@ -59,7 +59,7 @@ async function setupUser(userData) {
const owner = await models.User.findOne({role: 'Owner', status: 'all'}); const owner = await models.User.findOne({role: 'Owner', status: 'all'});
if (!owner) { if (!owner) {
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.setupUnableToRun) message: tpl(messages.setupUnableToRun)
}); });
} }

View File

@ -131,7 +131,7 @@ const transformEmailRecipientFilter = (emailRecipientFilter, {errorProperty = 'e
// `paid` and `free` were swapped out for NQL filters in 4.5.0, we shouldn't see them here now // `paid` and `free` were swapped out for NQL filters in 4.5.0, we shouldn't see them here now
case 'paid': case 'paid':
case 'free': case 'free':
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.unexpectedFilterError, { message: tpl(messages.unexpectedFilterError, {
property: errorProperty, property: errorProperty,
value: emailRecipientFilter value: emailRecipientFilter
@ -140,7 +140,7 @@ const transformEmailRecipientFilter = (emailRecipientFilter, {errorProperty = 'e
case 'all': case 'all':
return 'subscribed:true'; return 'subscribed:true';
case 'none': case 'none':
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.noneFilterError, { message: tpl(messages.noneFilterError, {
property: errorProperty property: errorProperty
}) })
@ -352,7 +352,7 @@ async function sendEmailJob({emailModel, options}) {
error: errorMessage error: errorMessage
}, {patch: true}); }, {patch: true});
throw new errors.GhostError({ throw new errors.InternalServerError({
err: error, err: error,
context: tpl(messages.sendEmailRequestFailed) context: tpl(messages.sendEmailRequestFailed)
}); });

View File

@ -314,12 +314,12 @@ class OEmbed {
return data; return data;
} catch (err) { } catch (err) {
// allow specific validation errors through for better error messages // allow specific validation errors through for better error messages
if (errors.utils.isIgnitionError(err) && err.errorType === 'ValidationError') { if (errors.utils.isGhostError(err) && err.errorType === 'ValidationError') {
throw err; throw err;
} }
// log the real error because we're going to throw a generic "Unknown provider" error // log the real error because we're going to throw a generic "Unknown provider" error
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
message: 'Encountered error when fetching oembed', message: 'Encountered error when fetching oembed',
err err
})); }));

View File

@ -128,7 +128,7 @@ CanThisResult.prototype.beginCheck = function (context) {
context = parseContext(context); context = parseContext(context);
if (actionsMap.empty()) { if (actionsMap.empty()) {
throw new errors.GhostError({message: tpl(messages.noActionsMapFoundError)}); throw new errors.InternalServerError({message: tpl(messages.noActionsMapFoundError)});
} }
// Kick off loading of user permissions if necessary // Kick off loading of user permissions if necessary

View File

@ -34,7 +34,7 @@ const readRedirectsFile = async (redirectsPath) => {
return ''; return '';
} }
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
throw err; throw err;
} }
@ -162,7 +162,7 @@ class CustomRedirectsAPI {
} }
} }
} catch (err) { } catch (err) {
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
logging.error(err); logging.error(err);
} else { } else {
logging.error(new errors.IncorrectUsageError({ logging.error(new errors.IncorrectUsageError({

View File

@ -48,7 +48,7 @@ class DefaultSettingsManager {
}); });
}).catch((error) => { }).catch((error) => {
// CASE: we might have a permission error, as we can't access the directory // CASE: we might have a permission error, as we can't access the directory
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.ensureSettings, { message: tpl(messages.ensureSettings, {
path: this.destinationFolderPath path: this.destinationFolderPath
}), }),

View File

@ -90,7 +90,7 @@ class RouteSettings {
return Promise.resolve([]); return Promise.resolve([]);
} }
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
throw err; throw err;
} }

View File

@ -36,11 +36,11 @@ class SettingsLoader {
return validate(object); return validate(object);
} catch (err) { } catch (err) {
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
throw err; throw err;
} }
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.settingsLoaderError, { message: tpl(messages.settingsLoaderError, {
setting: 'routes', setting: 'routes',
path: this.settingFilePath path: this.settingFilePath
@ -66,11 +66,11 @@ class SettingsLoader {
return validate(object); return validate(object);
} catch (err) { } catch (err) {
if (errors.utils.isIgnitionError(err)) { if (errors.utils.isGhostError(err)) {
throw err; throw err;
} }
throw new errors.GhostError({ throw new errors.InternalServerError({
message: tpl(messages.settingsLoaderError, { message: tpl(messages.settingsLoaderError, {
setting: 'routes', setting: 'routes',
path: this.settingFilePath path: this.settingFilePath

View File

@ -35,7 +35,7 @@ module.exports = function parseYaml(file) {
return parsed; return parsed;
} catch (error) { } catch (error) {
if (errors.utils.isIgnitionError(error)) { if (errors.utils.isGhostError(error)) {
throw error; throw error;
} }

View File

@ -136,7 +136,7 @@ function ping(post) {
'Content-type': 'application/json' 'Content-type': 'application/json'
} }
}).catch(function (err) { }).catch(function (err) {
logging.error(new errors.GhostError({ logging.error(new errors.InternalServerError({
err: err, err: err,
context: tpl(messages.requestFailedError, {service: 'slack'}), context: tpl(messages.requestFailedError, {service: 'slack'}),
help: tpl(messages.requestFailedHelp, {url: 'https://ghost.org/docs/'}) help: tpl(messages.requestFailedHelp, {url: 'https://ghost.org/docs/'})

View File

@ -112,7 +112,7 @@ module.exports = {
if (checkedTheme) { if (checkedTheme) {
fs.remove(checkedTheme.path) fs.remove(checkedTheme.path)
.catch((err) => { .catch((err) => {
logging.error(new errors.GhostError({err: err})); logging.error(new errors.InternalServerError({err: err}));
}); });
} }
@ -120,7 +120,7 @@ module.exports = {
getStorage() getStorage()
.delete(backupName) .delete(backupName)
.catch((err) => { .catch((err) => {
logging.error(new errors.GhostError({err: err})); logging.error(new errors.InternalServerError({err: err}));
}); });
} }
}, },

View File

@ -87,7 +87,7 @@ function ping(post) {
if (!goodResponse.test(res.body)) { if (!goodResponse.test(res.body)) {
const matches = res.body.match(errorMessage); const matches = res.body.match(errorMessage);
const message = matches ? matches[1] : res.body; const message = matches ? matches[1] : res.body;
throw new errors.GhostError({message}); throw new errors.InternalServerError({message});
} }
}) })
.catch(function (err) { .catch(function (err) {
@ -100,7 +100,7 @@ function ping(post) {
help: tpl(messages.requestFailedHelp, {url: 'https://ghost.org/docs/'}) help: tpl(messages.requestFailedHelp, {url: 'https://ghost.org/docs/'})
}); });
} else { } else {
error = new errors.GhostError({ error = new errors.InternalServerError({
err: err, err: err,
message: err.message, message: err.message,
context: tpl(messages.requestFailedError, {service: 'xmlrpc'}), context: tpl(messages.requestFailedError, {service: 'xmlrpc'}),

View File

@ -44,7 +44,7 @@ const notImplemented = function (req, res, next) {
} }
} }
next(new errors.GhostError({ next(new errors.InternalServerError({
errorType: 'NotImplementedError', errorType: 'NotImplementedError',
message: tpl(messages.notImplemented), message: tpl(messages.notImplemented),
statusCode: '501' statusCode: '501'

View File

@ -40,7 +40,7 @@ const notImplemented = function (req, res, next) {
} }
} }
next(new errors.GhostError({ next(new errors.InternalServerError({
errorType: 'NotImplementedError', errorType: 'NotImplementedError',
message: tpl(messages.notImplemented), message: tpl(messages.notImplemented),
statusCode: '501' statusCode: '501'

View File

@ -44,7 +44,7 @@ const notImplemented = function (req, res, next) {
} }
} }
next(new errors.GhostError({ next(new errors.InternalServerError({
errorType: 'NotImplementedError', errorType: 'NotImplementedError',
message: tpl(messages.notImplemented), message: tpl(messages.notImplemented),
statusCode: '501' statusCode: '501'

View File

@ -75,14 +75,14 @@ module.exports.prepareError = (err, req, res, next) => {
err = err[0]; err = err[0];
} }
if (!errors.utils.isIgnitionError(err)) { if (!errors.utils.isGhostError(err)) {
// We need a special case for 404 errors // We need a special case for 404 errors
if (err.statusCode && err.statusCode === 404) { if (err.statusCode && err.statusCode === 404) {
err = new errors.NotFoundError({ err = new errors.NotFoundError({
err: err err: err
}); });
} else { } else {
err = new errors.GhostError({ err = new errors.InternalServerError({
err: err, err: err,
message: err.message, message: err.message,
statusCode: err.statusCode statusCode: err.statusCode

View File

@ -18,7 +18,7 @@ if (sentryConfig && !sentryConfig.disabled) {
shouldHandleError(error) { shouldHandleError(error) {
// Sometimes non-Ghost issues will come into here but they won't // Sometimes non-Ghost issues will come into here but they won't
// have a statusCode so we should always handle them // have a statusCode so we should always handle them
if (!errors.utils.isIgnitionError(error)) { if (!errors.utils.isGhostError(error)) {
return true; return true;
} }

View File

@ -66,7 +66,7 @@
"@tryghost/debug": "0.1.9", "@tryghost/debug": "0.1.9",
"@tryghost/email-analytics-provider-mailgun": "1.0.5", "@tryghost/email-analytics-provider-mailgun": "1.0.5",
"@tryghost/email-analytics-service": "1.0.4", "@tryghost/email-analytics-service": "1.0.4",
"@tryghost/errors": "0.2.17", "@tryghost/errors": "1.0.4",
"@tryghost/express-dynamic-redirects": "0.2.1", "@tryghost/express-dynamic-redirects": "0.2.1",
"@tryghost/helpers": "1.1.54", "@tryghost/helpers": "1.1.54",
"@tryghost/image-transform": "1.0.18", "@tryghost/image-transform": "1.0.18",

View File

@ -308,7 +308,7 @@ describe('Post Model', function () {
}).then(function () { }).then(function () {
done(new Error('expected validation error')); done(new Error('expected validation error'));
}).catch(function (err) { }).catch(function (err) {
(err[0] instanceof errors.ValidationError).should.eql(true); err[0].name.should.eql('ValidationError');
done(); done();
}); });
}); });

View File

@ -102,7 +102,7 @@ describe('Unit: services/url/UrlService', function () {
urlService.getResource('/blog-post/'); urlService.getResource('/blog-post/');
throw new Error('Expected error.'); throw new Error('Expected error.');
} catch (err) { } catch (err) {
(err instanceof errors.InternalServerError).should.be.true(); errors.utils.isGhostError(err).should.be.true();
} }
}); });

View File

@ -375,7 +375,7 @@ describe('migrations/utils/permissions', function () {
runDownMigration = await runUpMigration(knex, migration); runDownMigration = await runUpMigration(knex, migration);
should.fail('addPermissionToRole up migration did not throw'); should.fail('addPermissionToRole up migration did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Cannot add permission(Unimaginable) with role(Not there) - permission does not exist'); err.message.should.equal('Cannot add permission(Unimaginable) with role(Not there) - permission does not exist');
} }
}); });
@ -408,7 +408,7 @@ describe('migrations/utils/permissions', function () {
await runUpMigration(knex, migration); await runUpMigration(knex, migration);
should.fail('addPermissionToRole did not throw'); should.fail('addPermissionToRole did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Cannot add permission(Permission Name) with role(Not there) - role does not exist'); err.message.should.equal('Cannot add permission(Permission Name) with role(Not there) - role does not exist');
} }
}); });

View File

@ -14,7 +14,7 @@ describe('schema commands', function () {
await commands._hasForeignSQLite({transaction: knex}); await commands._hasForeignSQLite({transaction: knex});
should.fail('addForeign did not throw'); should.fail('addForeign did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Must use hasForeignSQLite3 on an SQLite3 database'); err.message.should.equal('Must use hasForeignSQLite3 on an SQLite3 database');
} }
}); });
@ -29,7 +29,7 @@ describe('schema commands', function () {
await commands._hasPrimaryKeySQLite(null, knex); await commands._hasPrimaryKeySQLite(null, knex);
should.fail('hasPrimaryKeySQLite did not throw'); should.fail('hasPrimaryKeySQLite did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Must use hasPrimaryKeySQLite on an SQLite3 database'); err.message.should.equal('Must use hasPrimaryKeySQLite on an SQLite3 database');
} }
}); });

View File

@ -16,7 +16,7 @@ describe('MEGA', function () {
await addEmail(postModel); await addEmail(postModel);
should.fail('addEmail did not throw'); should.fail('addEmail did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Unexpected email_recipient_filter value "free", expected an NQL equivalent'); err.message.should.equal('Unexpected email_recipient_filter value "free", expected an NQL equivalent');
} }
}); });
@ -31,7 +31,7 @@ describe('MEGA', function () {
await addEmail(postModel); await addEmail(postModel);
should.fail('addEmail did not throw'); should.fail('addEmail did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Cannot send email to "none" email_recipient_filter'); err.message.should.equal('Cannot send email to "none" email_recipient_filter');
} }
}); });
@ -54,7 +54,7 @@ describe('MEGA', function () {
await _getEmailMemberRows({emailModel}); await _getEmailMemberRows({emailModel});
should.fail('getEmailMemberRows did not throw'); should.fail('getEmailMemberRows did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Unexpected recipient_filter value "paid", expected an NQL equivalent'); err.message.should.equal('Unexpected recipient_filter value "paid", expected an NQL equivalent');
} }
}); });
@ -68,7 +68,7 @@ describe('MEGA', function () {
await _getEmailMemberRows({emailModel}); await _getEmailMemberRows({emailModel});
should.fail('getEmailMemberRows did not throw'); should.fail('getEmailMemberRows did not throw');
} catch (err) { } catch (err) {
should.equal(err instanceof errors.GhostError, true); should.equal(errors.utils.isGhostError(err), true);
err.message.should.equal('Cannot send email to "none" recipient_filter'); err.message.should.equal('Cannot send email to "none" recipient_filter');
} }
}); });

View File

@ -82,7 +82,7 @@ describe('UNIT > SettingsLoader:', function () {
it('can handle errors from YAML parser', function (done) { it('can handle errors from YAML parser', function (done) {
const storageFolderPath = path.join(__dirname, '../../../../utils/fixtures/settings/'); const storageFolderPath = path.join(__dirname, '../../../../utils/fixtures/settings/');
yamlParserStub.throws(new errors.GhostError({ yamlParserStub.throws(new errors.InternalServerError({
message: 'could not parse yaml file', message: 'could not parse yaml file',
context: 'bad indentation of a mapping entry at line 5, column 10' context: 'bad indentation of a mapping entry at line 5, column 10'
})); }));

View File

@ -100,11 +100,11 @@ const login = (request, API_URL) => {
.then(function then(res) { .then(function then(res) {
if (res.statusCode === 302) { if (res.statusCode === 302) {
// This can happen if you already have an instance running e.g. if you've been using Ghost CLI recently // This can happen if you already have an instance running e.g. if you've been using Ghost CLI recently
return reject(new errors.GhostError({ return reject(new errors.InternalServerError({
message: 'Ghost is redirecting, do you have an instance already running on port 2369?' message: 'Ghost is redirecting, do you have an instance already running on port 2369?'
})); }));
} else if (res.statusCode !== 200 && res.statusCode !== 201) { } else if (res.statusCode !== 200 && res.statusCode !== 201) {
return reject(new errors.GhostError({ return reject(new errors.InternalServerError({
message: res.body.errors[0].message message: res.body.errors[0].message
})); }));
} }

View File

@ -1348,7 +1348,15 @@
ghost-ignition "^4.2.4" ghost-ignition "^4.2.4"
lodash "^4.17.20" lodash "^4.17.20"
"@tryghost/errors@0.2.17", "@tryghost/errors@^0.2.10", "@tryghost/errors@^0.2.11", "@tryghost/errors@^0.2.12", "@tryghost/errors@^0.2.13", "@tryghost/errors@^0.2.14", "@tryghost/errors@^0.2.16", "@tryghost/errors@^0.2.17", "@tryghost/errors@^0.2.9": "@tryghost/errors@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@tryghost/errors/-/errors-1.0.4.tgz#9692cfd4c27a269ddbce77d93d02cfa8c52cc7ad"
integrity sha512-ImfwkOc54Ur9zjYgPaG3Y9wFeH00eJnqClYBZSB5/K0T6nqTXnIOyFIq33vZkmXuxQLX1xRb82OeWYxHxgFWDA==
dependencies:
lodash "^4.17.21"
uuid "^8.3.2"
"@tryghost/errors@^0.2.10", "@tryghost/errors@^0.2.11", "@tryghost/errors@^0.2.12", "@tryghost/errors@^0.2.13", "@tryghost/errors@^0.2.14", "@tryghost/errors@^0.2.16", "@tryghost/errors@^0.2.17", "@tryghost/errors@^0.2.9":
version "0.2.17" version "0.2.17"
resolved "https://registry.yarnpkg.com/@tryghost/errors/-/errors-0.2.17.tgz#9b89f3845256ace5650593f41cc86d64965b56ed" resolved "https://registry.yarnpkg.com/@tryghost/errors/-/errors-0.2.17.tgz#9b89f3845256ace5650593f41cc86d64965b56ed"
integrity sha512-Mj+bedWOwfooNA8fQdp6gIcRvWcKhJ/hOyGzu6OLFDLgEosFEeuFgXE6SsAWkf9+9NTYX30w88qGIWZqOhEAmQ== integrity sha512-Mj+bedWOwfooNA8fQdp6gIcRvWcKhJ/hOyGzu6OLFDLgEosFEeuFgXE6SsAWkf9+9NTYX30w88qGIWZqOhEAmQ==