diff --git a/Gruntfile.js b/Gruntfile.js index 31fc04444b..7aca0619c2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -699,6 +699,8 @@ var path = require('path'), var done = this.async(); bootstrap().then(function () { done(); + }).catch(function (err) { + grunt.fail.fatal(err.stack); }); }); diff --git a/core/bootstrap.js b/core/bootstrap.js index 67664ca936..296818e0c6 100644 --- a/core/bootstrap.js +++ b/core/bootstrap.js @@ -13,7 +13,6 @@ var fs = require('fs'), appRoot = config().paths.appRoot, configExample = config().paths.configExample, - rejectMessage = 'Unable to load config', configFile; function readConfigFile(envVal) { @@ -27,25 +26,32 @@ function writeConfigFile() { if one doesn't exist. After that, start the server. */ fs.exists(configExample, function checkTemplate(templateExists) { var read, - write; + write, + error; if (!templateExists) { - return errors.logError(new Error('Could not locate a configuration file.'), appRoot, 'Please check your deployment for config.js or config.example.js.'); + error = new Error('Could not locate a configuration file.'); + error.context = appRoot; + error.help = 'Please check your deployment for config.js or config.example.js.'; + + return written.reject(error); } // Copy config.example.js => config.js read = fs.createReadStream(configExample); read.on('error', function (err) { - /*jshint unused:false*/ - return errors.logError(new Error('Could not open config.example.js for read.'), appRoot, 'Please check your deployment for config.js or config.example.js.'); + errors.logError(new Error('Could not open config.example.js for read.'), appRoot, 'Please check your deployment for config.js or config.example.js.'); + + return written.reject(err); }); - read.on('end', written.resolve); write = fs.createWriteStream(configFile); write.on('error', function (err) { - /*jshint unused:false*/ - return errors.logError(new Error('Could not open config.js for write.'), appRoot, 'Please check your deployment for config.js or config.example.js.'); + errors.logError(new Error('Could not open config.js for write.'), appRoot, 'Please check your deployment for config.js or config.example.js.'); + + return written.reject(err); }); + write.on('finish', written.resolve); read.pipe(write); }); @@ -62,34 +68,39 @@ function validateConfigEnvironment() { try { config = readConfigFile(envVal); - } catch (ignore) { - + } + catch (e) { + return when.reject(e); } // Check if we don't even have a config if (!config) { - errors.logError(new Error('Cannot find the configuration for the current NODE_ENV'), "NODE_ENV=" + envVal, + errors.logError(new Error('Cannot find the configuration for the current NODE_ENV'), 'NODE_ENV=' + envVal, 'Ensure your config.js has a section for the current NODE_ENV value and is formatted properly.'); - return when.reject(rejectMessage); + + return when.reject(new Error('Unable to load config for NODE_ENV=' + envVal)); } // Check that our url is valid if (!validator.isURL(config.url, { protocols: ['http', 'https'], require_protocol: true })) { errors.logError(new Error('Your site url in config.js is invalid.'), config.url, 'Please make sure this is a valid url before restarting'); - return when.reject(rejectMessage); + + return when.reject(new Error('invalid site url')); } parsedUrl = url.parse(config.url || 'invalid', false, true); if (/\/ghost(\/|$)/.test(parsedUrl.pathname)) { errors.logError(new Error('Your site url in config.js cannot contain a subdirectory called ghost.'), config.url, 'Please rename the subdirectory before restarting'); - return when.reject(rejectMessage); + + return when.reject(new Error('ghost subdirectory not allowed')); } // Check that we have database values if (!config.database || !config.database.client) { errors.logError(new Error('Your database configuration in config.js is invalid.'), JSON.stringify(config.database), 'Please make sure this is a valid Bookshelf database configuration'); - return when.reject(rejectMessage); + + return when.reject(new Error('invalid database configuration')); } hasHostAndPort = config.server && !!config.server.host && !!config.server.port; @@ -98,7 +109,8 @@ function validateConfigEnvironment() { // Check for valid server host and port values if (!config.server || !(hasHostAndPort || hasSocket)) { errors.logError(new Error('Your server values (socket, or host and port) in config.js are invalid.'), JSON.stringify(config.server), 'Please provide them before restarting.'); - return when.reject(rejectMessage); + + return when.reject(new Error('invalid server configuration')); } return when.resolve(config); @@ -118,9 +130,10 @@ function loadConfig(configFilePath) { if (!configExists) { pendingConfig = writeConfigFile(); } + when(pendingConfig).then(validateConfigEnvironment).then(function (rawConfig) { return config.init(rawConfig).then(loaded.resolve); - }).otherwise(loaded.reject); + }).catch(loaded.reject); }); return loaded.promise; diff --git a/core/index.js b/core/index.js index ef168993f8..68651a3106 100644 --- a/core/index.js +++ b/core/index.js @@ -21,16 +21,16 @@ function startGhost(options) { var ghost = require('./server'); return ghost(options.app) .then(deferred.resolve) - .otherwise(function (e) { + .catch(function (err) { // We don't return the rejected promise to stop // the propagation of the rejection and just // allow the user to manage what to do. - deferred.reject(e); + deferred.reject(err); }); } catch (e) { deferred.reject(e); } - }); + }).catch(deferred.reject); return deferred.promise; } diff --git a/core/test/unit/bootstrap_spec.js b/core/test/unit/bootstrap_spec.js index 2c7fe92c88..fa241cdb94 100644 --- a/core/test/unit/bootstrap_spec.js +++ b/core/test/unit/bootstrap_spec.js @@ -15,7 +15,6 @@ var should = require('should'), describe('Bootstrap', function () { var sandbox, - rejectMessage = bootstrap.__get__('rejectMessage'), overrideConfig = function (newConfig) { bootstrap.__set__('readConfigFile', sandbox.stub().returns( _.extend({}, defaultConfig, newConfig) @@ -30,7 +29,6 @@ describe('Bootstrap', function () { afterEach(function () { bootstrap = rewire('../../bootstrap'); sandbox.restore(); - }); it('loads the config file if one exists', function (done) { @@ -120,7 +118,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -134,7 +132,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -148,7 +146,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -162,7 +160,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -176,7 +174,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -189,7 +187,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -202,7 +200,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -215,7 +213,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -229,7 +227,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -243,7 +241,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -258,7 +256,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -294,7 +292,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -307,7 +305,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done); @@ -320,7 +318,7 @@ describe('Bootstrap', function () { done(expectedError); }).catch(function (err) { should.exist(err); - err.should.contain(rejectMessage); + err.should.be.an.Error; done(); }).catch(done);