Ghost/core/server/apps/index.js
Katharina Irrgang d81bc91bd2 Error creation (#7477)
refs #7116, refs #2001

- Changes the way Ghost errors are implemented to benefit from proper inheritance
- Moves all error definitions into a single file
- Changes the error constructor to take an options object, rather than needing the arguments to be passed in the correct order.
- Provides a wrapper so that any errors that haven't already been converted to GhostErrors get converted before they are displayed.

Summary of changes:

* 🐛  set NODE_ENV in config handler
*   add GhostError implementation (core/server/errors.js)
  - register all errors in one file
  - inheritance from GhostError
  - option pattern
* 🔥  remove all error files
*   wrap all errors into GhostError in case of HTTP
* 🎨  adaptions
  - option pattern for errors
  - use GhostError when needed
* 🎨  revert debug deletion and add TODO for error id's
2016-10-06 13:27:35 +01:00

102 lines
3.8 KiB
JavaScript

var _ = require('lodash'),
Promise = require('bluebird'),
logging = require('../logging'),
errors = require('../errors'),
api = require('../api'),
loader = require('./loader'),
i18n = require('../i18n'),
config = require('../config'),
// Holds the available apps
availableApps = {};
function getInstalledApps() {
return api.settings.read({context: {internal: true}, key: 'installedApps'}).then(function (response) {
var installed = response.settings[0];
installed.value = installed.value || '[]';
try {
installed = JSON.parse(installed.value);
} catch (e) {
return Promise.reject(e);
}
return installed.concat(config.get('internalApps'));
});
}
function saveInstalledApps(installedApps) {
return getInstalledApps().then(function (currentInstalledApps) {
var updatedAppsInstalled = _.difference(_.uniq(installedApps.concat(currentInstalledApps)), config.get('internalApps'));
return api.settings.edit({settings: [{key: 'installedApps', value: updatedAppsInstalled}]}, {context: {internal: true}});
});
}
module.exports = {
init: function () {
var appsToLoad;
try {
// We have to parse the value because it's a string
api.settings.read({context: {internal: true}, key: 'activeApps'}).then(function (response) {
var aApps = response.settings[0];
appsToLoad = JSON.parse(aApps.value) || [];
appsToLoad = appsToLoad.concat(config.get('internalApps'));
});
} catch (err) {
logging.error(new errors.GhostError({
err: err,
context: i18n.t('errors.apps.failedToParseActiveAppsSettings.context'),
help: i18n.t('errors.apps.failedToParseActiveAppsSettings.help')
}));
return Promise.resolve();
}
// Grab all installed apps, install any not already installed that are in appsToLoad.
return getInstalledApps().then(function (installedApps) {
var loadedApps = {},
recordLoadedApp = function (name, loadedApp) {
// After loading the app, add it to our hash of loaded apps
loadedApps[name] = loadedApp;
return Promise.resolve(loadedApp);
},
loadPromises = _.map(appsToLoad, function (app) {
// If already installed, just activate the app
if (_.includes(installedApps, app)) {
return loader.activateAppByName(app).then(function (loadedApp) {
return recordLoadedApp(app, loadedApp);
});
}
// Install, then activate the app
return loader.installAppByName(app).then(function () {
return loader.activateAppByName(app);
}).then(function (loadedApp) {
return recordLoadedApp(app, loadedApp);
});
});
return Promise.all(loadPromises).then(function () {
// Save our installed apps to settings
return saveInstalledApps(_.keys(loadedApps));
}).then(function () {
// Extend the loadedApps onto the available apps
_.extend(availableApps, loadedApps);
}).catch(function (err) {
logging.error(new errors.GhostError({
err: err,
context: i18n.t('errors.apps.appWillNotBeLoaded.error'),
help: i18n.t('errors.apps.appWillNotBeLoaded.help')
}));
});
});
},
availableApps: availableApps
};