mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-17 05:21:36 +03:00
8680099765
refs #8222 - differentiate between errors and fatal errors - use gscan errors in theme middleware - Adds a new `error()` method to `currentActiveTheme` constructor which will return the errors we receive from gscan - In middleware, if a theme couldn't be activated because it's invalid, we'll fetch the erros and send them to our error handler. We also use a new property `hideStack` to control, if the stack (in dev mode and if available) should be shown or the gscan errors (in prod mode, or in dev if no stack error) - In our error handler we use this conditional to send a new property `gscan` to our error theme - In `error.hbs` we'll iterate through possible `gscan` error objects and render them. - remove stack printing - stack for theme developers in development mode doesn't make sense - stack in production doesn't make sense - the stack is usually hard to read - if you are developer you can read the error stack on the server log - utils.packages: transform native error into Ghost error - use `onlyFatalErrors` for gscan format and differeniate fatal errors vo.2 - optimise bootstrap error handling - transform theme is missing into an error - add new translation key - show html tags for error.hbs template: rule
87 lines
3.7 KiB
JavaScript
87 lines
3.7 KiB
JavaScript
var debug = require('debug')('ghost:themes'),
|
|
events = require('../events'),
|
|
errors = require('../errors'),
|
|
logging = require('../logging'),
|
|
i18n = require('../i18n'),
|
|
themeLoader = require('./loader'),
|
|
active = require('./active'),
|
|
validate = require('./validate'),
|
|
Storage = require('./Storage'),
|
|
settingsCache = require('../settings/cache'),
|
|
themeStorage;
|
|
|
|
// @TODO: reduce the amount of things we expose to the outside world
|
|
// Make this a nice clean sensible API we can all understand!
|
|
module.exports = {
|
|
// Init themes module
|
|
// TODO: move this once we're clear what needs to happen here
|
|
init: function initThemes() {
|
|
var activeThemeName = settingsCache.get('active_theme'),
|
|
self = this;
|
|
|
|
debug('init themes', activeThemeName);
|
|
|
|
// Register a listener for server-start to load all themes
|
|
events.on('server:start', function readAllThemesOnServerStart() {
|
|
themeLoader.loadAllThemes();
|
|
});
|
|
|
|
// Just read the active theme for now
|
|
return themeLoader
|
|
.loadOneTheme(activeThemeName)
|
|
.then(function activeThemeHasLoaded(theme) {
|
|
// Validate
|
|
return validate
|
|
.check(theme)
|
|
.then(function resultHandler(checkedTheme) {
|
|
// CASE: inform that the theme has errors, but not fatal (theme still works)
|
|
if (checkedTheme.results.error.length) {
|
|
logging.warn(new errors.ThemeValidationError({
|
|
errorType: 'ThemeWorksButHasErrors',
|
|
message: i18n.t('errors.middleware.themehandler.themeHasErrors', {theme: activeThemeName}),
|
|
errorDetails: JSON.stringify(checkedTheme.results.error, null, '\t')
|
|
}));
|
|
}
|
|
|
|
debug('Activating theme (method A on boot)', activeThemeName);
|
|
self.activate(theme, checkedTheme);
|
|
})
|
|
.catch(function (err) {
|
|
if (err.errorDetails) {
|
|
logging.error(new errors.ThemeValidationError({
|
|
message: i18n.t('errors.middleware.themehandler.invalidTheme', {theme: activeThemeName}),
|
|
errorDetails: JSON.stringify(err.errorDetails, null, '\t')
|
|
}));
|
|
}
|
|
|
|
// CASE: we have to remember to show errors on blog
|
|
// `err.context` remembers the theme inside this property
|
|
active.set(theme, err.context, err);
|
|
});
|
|
})
|
|
.catch(function (err) {
|
|
// CASE: active theme is missing, we don't want to exit because the admin panel will still work
|
|
err.message = i18n.t('errors.middleware.themehandler.missingTheme', {theme: activeThemeName});
|
|
logging.error(err);
|
|
});
|
|
},
|
|
// Load themes, soon to be removed and exposed via specific function.
|
|
loadAll: themeLoader.loadAllThemes,
|
|
loadOne: themeLoader.loadOneTheme,
|
|
get storage() {
|
|
themeStorage = themeStorage || new Storage();
|
|
|
|
return themeStorage;
|
|
},
|
|
list: require('./list'),
|
|
validate: validate,
|
|
toJSON: require('./to-json'),
|
|
getActive: active.get,
|
|
activate: function activate(loadedTheme, checkedTheme) {
|
|
// no need to check the score, activation should be used in combination with validate.check
|
|
// Use the two theme objects to set the current active theme
|
|
active.set(loadedTheme, checkedTheme);
|
|
},
|
|
middleware: require('./middleware')
|
|
};
|