mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Replace error handler middleware with @tryghost/mw-error-handler (#13879)
refs: https://github.com/TryGhost/Toolbox/issues/137 Extract error handling middleware and replace with a package.
This commit is contained in:
parent
271d2c02b0
commit
97c68dd388
20 changed files with 84 additions and 285 deletions
|
@ -7,7 +7,7 @@ const config = require('../../../shared/config');
|
|||
const helpers = require('../../services/routing/helpers');
|
||||
|
||||
// @TODO: make this properly shared code
|
||||
const shared = require('../../../server/web/shared/middleware/error-handler');
|
||||
const {prepareError} = require('@tryghost/mw-error-handler');
|
||||
|
||||
const messages = {
|
||||
oopsErrorTemplateHasError: 'Oops, seems there is an error in the error template.',
|
||||
|
@ -85,7 +85,7 @@ const themeErrorRenderer = (err, req, res, next) => {
|
|||
|
||||
module.exports.handleThemeResponse = [
|
||||
// Make sure the error can be served
|
||||
shared.prepareError,
|
||||
prepareError,
|
||||
// Handle the error in Sentry
|
||||
sentry.errorHandler,
|
||||
// Render the error using theme template
|
||||
|
|
|
@ -20,6 +20,7 @@ const offersService = require('../../server/services/offers');
|
|||
const customRedirects = require('../../server/services/redirects');
|
||||
const siteRoutes = require('./routes');
|
||||
const shared = require('../../server/web/shared');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
const mw = require('./middleware');
|
||||
const labs = require('../../shared/labs');
|
||||
|
||||
|
@ -176,7 +177,7 @@ module.exports = function setupSiteApp(options = {}) {
|
|||
siteApp.use(SiteRouter);
|
||||
|
||||
// ### Error handlers
|
||||
siteApp.use(shared.middleware.errorHandler.pageNotFound);
|
||||
siteApp.use(errorHandler.pageNotFound);
|
||||
config.get('apps:internal').forEach((appName) => {
|
||||
const app = require(path.join(config.get('paths').internalAppPath, appName));
|
||||
|
||||
|
|
|
@ -16,14 +16,11 @@ class MembersConfigProvider {
|
|||
* @param {{get: (key: string) => any}} options.settingsCache
|
||||
* @param {{get: (key: string) => any}} options.config
|
||||
* @param {any} options.urlUtils
|
||||
* @param {any} options.logging
|
||||
* @param {{original: string}} options.ghostVersion
|
||||
*/
|
||||
constructor(options) {
|
||||
this._settingsCache = options.settingsCache;
|
||||
this._config = options.config;
|
||||
this._urlUtils = options.urlUtils;
|
||||
this._ghostVersion = options.ghostVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,7 +13,6 @@ const labsService = require('../../../shared/labs');
|
|||
const settingsCache = require('../../../shared/settings-cache');
|
||||
const config = require('../../../shared/config');
|
||||
const models = require('../../models');
|
||||
const ghostVersion = require('@tryghost/version');
|
||||
const _ = require('lodash');
|
||||
const {GhostMailer} = require('../mail');
|
||||
const jobsService = require('../jobs');
|
||||
|
@ -35,8 +34,7 @@ const ghostMailer = new GhostMailer();
|
|||
const membersConfig = new MembersConfigProvider({
|
||||
config,
|
||||
settingsCache,
|
||||
urlUtils,
|
||||
ghostVersion
|
||||
urlUtils
|
||||
});
|
||||
|
||||
let membersApi;
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
const settingsCache = require('../../../shared/settings-cache');
|
||||
const ghostVersion = require('@tryghost/version');
|
||||
const Notifications = require('./notifications');
|
||||
const models = require('../../models');
|
||||
|
||||
module.exports.notifications = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: ghostVersion.full,
|
||||
SettingsModel: models.Settings
|
||||
});
|
||||
|
|
|
@ -3,6 +3,7 @@ const semver = require('semver');
|
|||
const Promise = require('bluebird');
|
||||
const _ = require('lodash');
|
||||
const errors = require('@tryghost/errors');
|
||||
const ghostVersion = require('@tryghost/version');
|
||||
const tpl = require('@tryghost/tpl');
|
||||
const ObjectId = require('bson-objectid');
|
||||
|
||||
|
@ -16,12 +17,10 @@ class Notifications {
|
|||
*
|
||||
* @param {Object} options
|
||||
* @param {Object} options.settingsCache - settings cache instance
|
||||
* @param {String} options.ghostVersion - Ghost instance version in "full" format - major.minor.patch
|
||||
* @param {Object} options.SettingsModel - Ghost's Setting model instance
|
||||
*/
|
||||
constructor({settingsCache, ghostVersion, SettingsModel}) {
|
||||
constructor({settingsCache, SettingsModel}) {
|
||||
this.settingsCache = settingsCache;
|
||||
this.ghostVersion = ghostVersion;
|
||||
this.SettingsModel = SettingsModel;
|
||||
}
|
||||
|
||||
|
@ -74,7 +73,7 @@ class Notifications {
|
|||
browse({user}) {
|
||||
let allNotifications = this.fetchAllNotifications();
|
||||
allNotifications = _.orderBy(allNotifications, 'addedAt', 'desc');
|
||||
const blogVersion = this.ghostVersion.match(/^(\d+\.)(\d+\.)(\d+)/);
|
||||
const blogVersion = ghostVersion.full.match(/^(\d+\.)(\d+\.)(\d+)/);
|
||||
|
||||
allNotifications = allNotifications.filter((notification) => {
|
||||
if (notification.createdAtVersion && !this.wasSeen(notification, user)) {
|
||||
|
@ -128,7 +127,7 @@ class Notifications {
|
|||
location: 'bottom',
|
||||
status: 'alert',
|
||||
id: ObjectId().toHexString(),
|
||||
createdAtVersion: this.ghostVersion
|
||||
createdAtVersion: ghostVersion.full
|
||||
};
|
||||
|
||||
const overrides = {
|
||||
|
|
|
@ -5,6 +5,8 @@ const config = require('../../../shared/config');
|
|||
const constants = require('@tryghost/constants');
|
||||
const urlUtils = require('../../../shared/url-utils');
|
||||
const shared = require('../shared');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
const sentry = require('../../../shared/sentry');
|
||||
const redirectAdminUrls = require('./middleware/redirect-admin-urls');
|
||||
|
||||
module.exports = function setupAdminApp() {
|
||||
|
@ -44,8 +46,8 @@ module.exports = function setupAdminApp() {
|
|||
// Finally, routing
|
||||
adminApp.get('*', require('./controller'));
|
||||
|
||||
adminApp.use(shared.middleware.errorHandler.pageNotFound);
|
||||
adminApp.use(shared.middleware.errorHandler.handleHTMLResponse);
|
||||
adminApp.use(errorHandler.pageNotFound);
|
||||
adminApp.use(errorHandler.handleHTMLResponse(sentry));
|
||||
|
||||
debug('Admin setup end');
|
||||
|
||||
|
|
|
@ -2,7 +2,8 @@ const debug = require('@tryghost/debug')('web:api:default:app');
|
|||
const config = require('../../../shared/config');
|
||||
const express = require('../../../shared/express');
|
||||
const urlUtils = require('../../../shared/url-utils');
|
||||
const errorHandler = require('../shared/middleware/error-handler');
|
||||
const sentry = require('../../../shared/sentry');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Parent API setup start');
|
||||
|
@ -26,7 +27,7 @@ module.exports = function setupApiApp() {
|
|||
|
||||
// Error handling for requests to non-existent API versions
|
||||
apiApp.use(errorHandler.resourceNotFound);
|
||||
apiApp.use(errorHandler.handleJSONResponse);
|
||||
apiApp.use(errorHandler.handleJSONResponse(sentry));
|
||||
|
||||
debug('Parent API setup end');
|
||||
return apiApp;
|
||||
|
|
|
@ -4,6 +4,8 @@ const express = require('../../../../../shared/express');
|
|||
const bodyParser = require('body-parser');
|
||||
const shared = require('../../../shared');
|
||||
const apiMw = require('../../middleware');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
const sentry = require('../../../../../shared/sentry');
|
||||
const routes = require('./routes');
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
|
@ -30,8 +32,8 @@ module.exports = function setupApiApp() {
|
|||
apiApp.use(routes());
|
||||
|
||||
// API error handling
|
||||
apiApp.use(shared.middleware.errorHandler.resourceNotFound);
|
||||
apiApp.use(shared.middleware.errorHandler.handleJSONResponseV2);
|
||||
apiApp.use(errorHandler.resourceNotFound);
|
||||
apiApp.use(errorHandler.handleJSONResponseV2(sentry));
|
||||
|
||||
debug('Admin API canary setup end');
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@ const debug = require('@tryghost/debug')('web:api:canary:content:app');
|
|||
const boolParser = require('express-query-boolean');
|
||||
const bodyParser = require('body-parser');
|
||||
const express = require('../../../../../shared/express');
|
||||
const sentry = require('../../../../../shared/sentry');
|
||||
const shared = require('../../../shared');
|
||||
const routes = require('./routes');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Content API canary setup start');
|
||||
|
@ -24,8 +26,8 @@ module.exports = function setupApiApp() {
|
|||
apiApp.use(routes());
|
||||
|
||||
// API error handling
|
||||
apiApp.use(shared.middleware.errorHandler.resourceNotFound);
|
||||
apiApp.use(shared.middleware.errorHandler.handleJSONResponse);
|
||||
apiApp.use(errorHandler.resourceNotFound);
|
||||
apiApp.use(errorHandler.handleJSONResponse(sentry));
|
||||
|
||||
debug('Content API canary setup end');
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
const debug = require('@tryghost/debug')('web:v2:admin:app');
|
||||
const boolParser = require('express-query-boolean');
|
||||
const express = require('../../../../../shared/express');
|
||||
const sentry = require('../../../../../shared/sentry');
|
||||
const bodyParser = require('body-parser');
|
||||
const shared = require('../../../shared');
|
||||
const apiMw = require('../../middleware');
|
||||
const routes = require('./routes');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Admin API v2 setup start');
|
||||
|
@ -30,8 +32,8 @@ module.exports = function setupApiApp() {
|
|||
apiApp.use(routes());
|
||||
|
||||
// API error handling
|
||||
apiApp.use(shared.middleware.errorHandler.resourceNotFound);
|
||||
apiApp.use(shared.middleware.errorHandler.handleJSONResponseV2);
|
||||
apiApp.use(errorHandler.resourceNotFound);
|
||||
apiApp.use(errorHandler.handleJSONResponseV2(sentry));
|
||||
|
||||
debug('Admin API v2 setup end');
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@ const debug = require('@tryghost/debug')('web:api:v2:content:app');
|
|||
const boolParser = require('express-query-boolean');
|
||||
const bodyParser = require('body-parser');
|
||||
const express = require('../../../../../shared/express');
|
||||
const sentry = require('../../../../../shared/sentry');
|
||||
const shared = require('../../../shared');
|
||||
const routes = require('./routes');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Content API v2 setup start');
|
||||
|
@ -24,8 +26,8 @@ module.exports = function setupApiApp() {
|
|||
apiApp.use(routes());
|
||||
|
||||
// API error handling
|
||||
apiApp.use(shared.middleware.errorHandler.resourceNotFound);
|
||||
apiApp.use(shared.middleware.errorHandler.handleJSONResponse);
|
||||
apiApp.use(errorHandler.resourceNotFound);
|
||||
apiApp.use(errorHandler.handleJSONResponse(sentry));
|
||||
|
||||
debug('Content API v2 setup end');
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
const debug = require('@tryghost/debug')('web:v3:admin:app');
|
||||
const boolParser = require('express-query-boolean');
|
||||
const express = require('../../../../../shared/express');
|
||||
const sentry = require('../../../../../shared/sentry');
|
||||
const bodyParser = require('body-parser');
|
||||
const shared = require('../../../shared');
|
||||
const apiMw = require('../../middleware');
|
||||
const routes = require('./routes');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Admin API v3 setup start');
|
||||
|
@ -30,8 +32,8 @@ module.exports = function setupApiApp() {
|
|||
apiApp.use(routes());
|
||||
|
||||
// API error handling
|
||||
apiApp.use(shared.middleware.errorHandler.resourceNotFound);
|
||||
apiApp.use(shared.middleware.errorHandler.handleJSONResponseV2);
|
||||
apiApp.use(errorHandler.resourceNotFound);
|
||||
apiApp.use(errorHandler.handleJSONResponseV2(sentry));
|
||||
|
||||
debug('Admin API v3 setup end');
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@ const debug = require('@tryghost/debug')('web:api:v3:content:app');
|
|||
const boolParser = require('express-query-boolean');
|
||||
const bodyParser = require('body-parser');
|
||||
const express = require('../../../../../shared/express');
|
||||
const sentry = require('../../../../../shared/sentry');
|
||||
const shared = require('../../../shared');
|
||||
const routes = require('./routes');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
|
||||
module.exports = function setupApiApp() {
|
||||
debug('Content API v3 setup start');
|
||||
|
@ -24,8 +26,8 @@ module.exports = function setupApiApp() {
|
|||
apiApp.use(routes());
|
||||
|
||||
// API error handling
|
||||
apiApp.use(shared.middleware.errorHandler.resourceNotFound);
|
||||
apiApp.use(shared.middleware.errorHandler.handleJSONResponse);
|
||||
apiApp.use(errorHandler.resourceNotFound);
|
||||
apiApp.use(errorHandler.handleJSONResponse(sentry));
|
||||
|
||||
debug('Content API v3 setup end');
|
||||
|
||||
|
|
|
@ -4,10 +4,12 @@ const cors = require('cors');
|
|||
const bodyParser = require('body-parser');
|
||||
const express = require('../../../shared/express');
|
||||
const urlUtils = require('../../../shared/url-utils');
|
||||
const sentry = require('../../../shared/sentry');
|
||||
const membersService = require('../../services/members');
|
||||
const middleware = membersService.middleware;
|
||||
const shared = require('../shared');
|
||||
const labs = require('../../../shared/labs');
|
||||
const errorHandler = require('@tryghost/mw-error-handler');
|
||||
|
||||
module.exports = function setupMembersApp() {
|
||||
debug('Members App setup start');
|
||||
|
@ -46,12 +48,12 @@ module.exports = function setupMembersApp() {
|
|||
membersApp.post('/api/events', labs.enabledMiddleware('membersActivity'), middleware.loadMemberSession, (req, res, next) => membersService.api.middleware.createEvents(req, res, next));
|
||||
|
||||
// API error handling
|
||||
membersApp.use('/api', shared.middleware.errorHandler.resourceNotFound);
|
||||
membersApp.use('/api', shared.middleware.errorHandler.handleJSONResponseV2);
|
||||
membersApp.use('/api', errorHandler.resourceNotFound);
|
||||
membersApp.use('/api', errorHandler.handleJSONResponseV2(sentry));
|
||||
|
||||
// Webhook error handling
|
||||
membersApp.use('/webhooks', shared.middleware.errorHandler.resourceNotFound);
|
||||
membersApp.use('/webhooks', shared.middleware.errorHandler.handleJSONResponseV2);
|
||||
membersApp.use('/webhooks', errorHandler.resourceNotFound);
|
||||
membersApp.use('/webhooks', errorHandler.handleJSONResponseV2(sentry));
|
||||
|
||||
debug('Members App setup end');
|
||||
|
||||
|
|
|
@ -1,224 +0,0 @@
|
|||
const _ = require('lodash');
|
||||
const debug = require('@tryghost/debug')('error-handler');
|
||||
const errors = require('@tryghost/errors');
|
||||
const tpl = require('@tryghost/tpl');
|
||||
const sentry = require('../../../../shared/sentry');
|
||||
|
||||
const messages = {
|
||||
pageNotFound: 'Page not found',
|
||||
resourceNotFound: 'Resource not found',
|
||||
actions: {
|
||||
images: {
|
||||
upload: 'upload image'
|
||||
}
|
||||
},
|
||||
userMessages: {
|
||||
BookshelfRelationsError: 'Database error, cannot {action}.',
|
||||
InternalServerError: 'Internal server error, cannot {action}.',
|
||||
IncorrectUsageError: 'Incorrect usage error, cannot {action}.',
|
||||
NotFoundError: 'Resource not found error, cannot {action}.',
|
||||
BadRequestError: 'Request not understood error, cannot {action}.',
|
||||
UnauthorizedError: 'Authorisation error, cannot {action}.',
|
||||
NoPermissionError: 'Permission error, cannot {action}.',
|
||||
ValidationError: 'Validation error, cannot {action}.',
|
||||
UnsupportedMediaTypeError: 'Unsupported media error, cannot {action}.',
|
||||
TooManyRequestsError: 'Too many requests error, cannot {action}.',
|
||||
MaintenanceError: 'Server down for maintenance, cannot {action}.',
|
||||
MethodNotAllowedError: 'Method not allowed, cannot {action}.',
|
||||
RequestEntityTooLargeError: 'Request too large, cannot {action}.',
|
||||
TokenRevocationError: 'Token is not available, cannot {action}.',
|
||||
VersionMismatchError: 'Version mismatch error, cannot {action}.',
|
||||
DataExportError: 'Error exporting content.',
|
||||
DataImportError: 'Duplicated entry, cannot save {action}.',
|
||||
DatabaseVersionError: 'Database version compatibility error, cannot {action}.',
|
||||
EmailError: 'Error sending email!',
|
||||
ThemeValidationError: 'Theme validation error, cannot {action}.',
|
||||
HostLimitError: 'Host Limit error, cannot {action}.',
|
||||
DisabledFeatureError: 'Theme validation error, the {{{helperName}}} helper is not available. Cannot {action}.',
|
||||
UpdateCollisionError: 'Saving failed! Someone else is editing this post.'
|
||||
}
|
||||
};
|
||||
|
||||
const updateStack = (err) => {
|
||||
let stackbits = err.stack.split(/\n/g);
|
||||
|
||||
// We build this up backwards, so we always insert at position 1
|
||||
|
||||
if (process.env.NODE_ENV === 'production' || err.statusCode === 404) {
|
||||
// In production mode, remove the stack trace
|
||||
stackbits.splice(1, stackbits.length - 1);
|
||||
} else {
|
||||
// In dev mode, clearly mark the strack trace
|
||||
stackbits.splice(1, 0, `Stack Trace:`);
|
||||
}
|
||||
|
||||
// Add in our custom cotext and help methods
|
||||
|
||||
if (err.help) {
|
||||
stackbits.splice(1, 0, `${err.help}`);
|
||||
}
|
||||
|
||||
if (err.context) {
|
||||
stackbits.splice(1, 0, `${err.context}`);
|
||||
}
|
||||
|
||||
return stackbits.join('\n');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get an error ready to be shown the the user
|
||||
*/
|
||||
module.exports.prepareError = (err, req, res, next) => {
|
||||
debug(err);
|
||||
|
||||
if (Array.isArray(err)) {
|
||||
err = err[0];
|
||||
}
|
||||
|
||||
if (!errors.utils.isGhostError(err)) {
|
||||
// We need a special case for 404 errors
|
||||
if (err.statusCode && err.statusCode === 404) {
|
||||
err = new errors.NotFoundError({
|
||||
err: err
|
||||
});
|
||||
} else if (err.stack.match(/node_modules\/handlebars\//)) {
|
||||
// Temporary handling of theme errors from handlebars
|
||||
// @TODO remove this when #10496 is solved properly
|
||||
err = new errors.IncorrectUsageError({
|
||||
err: err,
|
||||
message: err.message,
|
||||
statusCode: err.statusCode
|
||||
});
|
||||
} else {
|
||||
err = new errors.InternalServerError({
|
||||
err: err,
|
||||
message: err.message,
|
||||
statusCode: err.statusCode
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// used for express logging middleware see core/server/app.js
|
||||
req.err = err;
|
||||
|
||||
// alternative for res.status();
|
||||
res.statusCode = err.statusCode;
|
||||
|
||||
err.stack = updateStack(err);
|
||||
|
||||
// never cache errors
|
||||
res.set({
|
||||
'Cache-Control': 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0'
|
||||
});
|
||||
|
||||
next(err);
|
||||
};
|
||||
|
||||
const jsonErrorRenderer = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
||||
res.json({
|
||||
errors: [{
|
||||
message: err.message,
|
||||
context: err.context,
|
||||
help: err.help,
|
||||
errorType: err.errorType,
|
||||
errorDetails: err.errorDetails,
|
||||
ghostErrorCode: err.ghostErrorCode
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
const jsonErrorRendererV2 = (err, req, res, next) => { // eslint-disable-line no-unused-vars
|
||||
const userError = prepareUserMessage(err, req);
|
||||
|
||||
res.json({
|
||||
errors: [{
|
||||
message: userError.message || null,
|
||||
context: userError.context || null,
|
||||
type: err.errorType || null,
|
||||
details: err.errorDetails || null,
|
||||
property: err.property || null,
|
||||
help: err.help || null,
|
||||
code: err.code || null,
|
||||
id: err.id || null
|
||||
}]
|
||||
});
|
||||
};
|
||||
|
||||
const prepareUserMessage = (err, res) => {
|
||||
const userError = {
|
||||
message: err.message,
|
||||
context: err.context
|
||||
};
|
||||
|
||||
const docName = _.get(res, 'frameOptions.docName');
|
||||
const method = _.get(res, 'frameOptions.method');
|
||||
|
||||
if (docName && method) {
|
||||
let action;
|
||||
|
||||
const actionMap = {
|
||||
browse: 'list',
|
||||
read: 'read',
|
||||
add: 'save',
|
||||
edit: 'edit',
|
||||
destroy: 'delete'
|
||||
};
|
||||
|
||||
if (_.get(messages.actions, [docName, method])) {
|
||||
action = tpl(messages.actions[docName][method]);
|
||||
} else if (Object.keys(actionMap).includes(method)) {
|
||||
let resource = docName;
|
||||
|
||||
if (method !== 'browse') {
|
||||
resource = resource.replace(/s$/, '');
|
||||
}
|
||||
|
||||
action = `${actionMap[method]} ${resource}`;
|
||||
}
|
||||
|
||||
if (action) {
|
||||
if (err.context) {
|
||||
userError.context = `${err.message} ${err.context}`;
|
||||
} else {
|
||||
userError.context = err.message;
|
||||
}
|
||||
|
||||
userError.message = tpl(messages.userMessages[err.name], {action: action});
|
||||
}
|
||||
}
|
||||
|
||||
return userError;
|
||||
};
|
||||
|
||||
module.exports.resourceNotFound = (req, res, next) => {
|
||||
next(new errors.NotFoundError({message: tpl(messages.resourceNotFound)}));
|
||||
};
|
||||
|
||||
module.exports.pageNotFound = (req, res, next) => {
|
||||
next(new errors.NotFoundError({message: tpl(messages.pageNotFound)}));
|
||||
};
|
||||
|
||||
module.exports.handleJSONResponse = [
|
||||
// Make sure the error can be served
|
||||
module.exports.prepareError,
|
||||
// Handle the error in Sentry
|
||||
sentry.errorHandler,
|
||||
// Render the error using JSON format
|
||||
jsonErrorRenderer
|
||||
];
|
||||
|
||||
module.exports.handleJSONResponseV2 = [
|
||||
// Make sure the error can be served
|
||||
module.exports.prepareError,
|
||||
// Handle the error in Sentry
|
||||
sentry.errorHandler,
|
||||
// Render the error using JSON format
|
||||
jsonErrorRendererV2
|
||||
];
|
||||
|
||||
module.exports.handleHTMLResponse = [
|
||||
// Make sure the error can be served
|
||||
module.exports.prepareError,
|
||||
// Handle the error in Sentry
|
||||
sentry.errorHandler
|
||||
];
|
|
@ -11,10 +11,6 @@ module.exports = {
|
|||
return require('./cache-control');
|
||||
},
|
||||
|
||||
get errorHandler() {
|
||||
return require('./error-handler');
|
||||
},
|
||||
|
||||
get prettyUrls() {
|
||||
return require('./pretty-urls');
|
||||
},
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
"@tryghost/debug": "0.1.9",
|
||||
"@tryghost/email-analytics-provider-mailgun": "1.0.7",
|
||||
"@tryghost/email-analytics-service": "1.0.5",
|
||||
"@tryghost/errors": "1.1.1",
|
||||
"@tryghost/errors": "1.2.0",
|
||||
"@tryghost/express-dynamic-redirects": "0.2.2",
|
||||
"@tryghost/helpers": "1.1.54",
|
||||
"@tryghost/image-transform": "1.0.25",
|
||||
|
@ -86,6 +86,7 @@
|
|||
"@tryghost/members-ssr": "1.0.16",
|
||||
"@tryghost/metrics": "1.0.1",
|
||||
"@tryghost/minifier": "0.1.8",
|
||||
"@tryghost/mw-error-handler": "0.1.1",
|
||||
"@tryghost/mw-session-from-token": "0.1.26",
|
||||
"@tryghost/nodemailer": "0.3.8",
|
||||
"@tryghost/package-json": "1.0.13",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const should = require('should');
|
||||
const sinon = require('sinon');
|
||||
|
||||
const ghostVersion = require('@tryghost/version');
|
||||
const moment = require('moment');
|
||||
const Notifications = require('../../../../../core/server/services/notifications/notifications');
|
||||
const {owner} = require('../../../../utils/fixtures/context');
|
||||
|
@ -13,9 +14,9 @@ describe('Notifications Service', function () {
|
|||
get: sinon.fake.returns(existingNotifications)
|
||||
};
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('4.1.0');
|
||||
const notificationsSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '4.1.0'
|
||||
settingsCache
|
||||
});
|
||||
|
||||
const {allNotifications, notificationsToAdd} = notificationsSvc.add({
|
||||
|
@ -60,9 +61,9 @@ describe('Notifications Service', function () {
|
|||
}])
|
||||
};
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('4.1.0');
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '4.1.0'
|
||||
settingsCache
|
||||
});
|
||||
|
||||
const notifications = notificationSvc.browse({user: owner});
|
||||
|
@ -89,9 +90,9 @@ describe('Notifications Service', function () {
|
|||
}])
|
||||
};
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('4.0.0');
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '4.0.0'
|
||||
settingsCache
|
||||
});
|
||||
|
||||
const notifications = notificationSvc.browse({user: owner});
|
||||
|
@ -118,9 +119,9 @@ describe('Notifications Service', function () {
|
|||
}])
|
||||
};
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('3.0.0');
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '3.0.0'
|
||||
settingsCache
|
||||
});
|
||||
|
||||
const notifications = notificationSvc.browse({user: owner});
|
||||
|
@ -147,9 +148,9 @@ describe('Notifications Service', function () {
|
|||
}])
|
||||
};
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('4.0.0');
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '4.0.0'
|
||||
settingsCache
|
||||
});
|
||||
|
||||
const notifications = notificationSvc.browse({user: owner});
|
||||
|
@ -176,9 +177,9 @@ describe('Notifications Service', function () {
|
|||
}])
|
||||
};
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('5.0.0');
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '5.0.0'
|
||||
settingsCache
|
||||
});
|
||||
|
||||
const notifications = notificationSvc.browse({user: owner});
|
||||
|
@ -218,9 +219,9 @@ describe('Notifications Service', function () {
|
|||
}])
|
||||
};
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('4.1.0');
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '4.1.0'
|
||||
settingsCache
|
||||
});
|
||||
|
||||
const notifications = notificationSvc.browse({user: owner});
|
||||
|
@ -243,7 +244,6 @@ describe('Notifications Service', function () {
|
|||
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '5.0.0',
|
||||
SettingsModel: {
|
||||
edit: settingsModelStub
|
||||
}
|
||||
|
@ -269,9 +269,9 @@ describe('Notifications Service', function () {
|
|||
};
|
||||
const settingsModelStub = sinon.stub().resolves();
|
||||
|
||||
sinon.stub(ghostVersion, 'full').value('5.0.0');
|
||||
const notificationSvc = new Notifications({
|
||||
settingsCache,
|
||||
ghostVersion: '5.0.0',
|
||||
SettingsModel: {
|
||||
edit: settingsModelStub
|
||||
}
|
||||
|
|
24
yarn.lock
24
yarn.lock
|
@ -1412,10 +1412,10 @@
|
|||
"@tryghost/debug" "^0.1.9"
|
||||
lodash "^4.17.20"
|
||||
|
||||
"@tryghost/errors@1.1.1", "@tryghost/errors@^1.0.0", "@tryghost/errors@^1.1.0", "@tryghost/errors@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/@tryghost/errors/-/errors-1.1.1.tgz"
|
||||
integrity sha512-na0qB5sdy1BWgquzn+m530ohJ3fTeF451xUTR7I8b76TBEL9snnIkXCv5Qdjmnevmgod7aAGsHi2syyKFlvEvQ==
|
||||
"@tryghost/errors@1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/errors/-/errors-1.2.0.tgz#989f10434a17286e952b5a9434e50846ea4ad87c"
|
||||
integrity sha512-80I7LmRgPQt380Bm/90hF8KPkkNqOFHF2T6oO+NXkLd+UTc1qLOfe6nZS17WD9glMmHrqv6IF8U1MjPMDa4VOQ==
|
||||
dependencies:
|
||||
lodash "^4.17.21"
|
||||
uuid "^8.3.2"
|
||||
|
@ -1428,6 +1428,14 @@
|
|||
"@tryghost/ignition-errors" "^0.1.0"
|
||||
lodash "^4.17.21"
|
||||
|
||||
"@tryghost/errors@^1.0.0", "@tryghost/errors@^1.1.0", "@tryghost/errors@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/@tryghost/errors/-/errors-1.1.1.tgz"
|
||||
integrity sha512-na0qB5sdy1BWgquzn+m530ohJ3fTeF451xUTR7I8b76TBEL9snnIkXCv5Qdjmnevmgod7aAGsHi2syyKFlvEvQ==
|
||||
dependencies:
|
||||
lodash "^4.17.21"
|
||||
uuid "^8.3.2"
|
||||
|
||||
"@tryghost/express-dynamic-redirects@0.2.2":
|
||||
version "0.2.2"
|
||||
resolved "https://registry.npmjs.org/@tryghost/express-dynamic-redirects/-/express-dynamic-redirects-0.2.2.tgz"
|
||||
|
@ -1712,6 +1720,14 @@
|
|||
mobiledoc-dom-renderer "0.7.0"
|
||||
mobiledoc-text-renderer "0.4.0"
|
||||
|
||||
"@tryghost/mw-error-handler@0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@tryghost/mw-error-handler/-/mw-error-handler-0.1.1.tgz#47ad5f534b21ec71db00706f47622d660cde894b"
|
||||
integrity sha512-c1EMdeU5k6FpB640GxjA2sUsyCuTPW8qlWJu1eZAbX/63YBMZOoBkvGNadUM5hdJ1fGwwFQME2j1vzkQ+qRMHg==
|
||||
dependencies:
|
||||
"@tryghost/debug" "^0.1.9"
|
||||
"@tryghost/tpl" "^0.1.8"
|
||||
|
||||
"@tryghost/mw-session-from-token@0.1.26":
|
||||
version "0.1.26"
|
||||
resolved "https://registry.npmjs.org/@tryghost/mw-session-from-token/-/mw-session-from-token-0.1.26.tgz"
|
||||
|
|
Loading…
Add table
Reference in a new issue