Merge pull request #878 from jgable/configErrorMessages

This commit is contained in:
Hannah Wolfe 2013-09-26 23:12:05 +01:00
commit c976a094f6
3 changed files with 78 additions and 38 deletions

View File

@ -1,5 +1,7 @@
var fs = require('fs'), var fs = require('fs'),
when = require('when'); url = require('url'),
when = require('when'),
errors = require('./server/errorHandling');
function writeConfigFile() { function writeConfigFile() {
var written = when.defer(); var written = when.defer();
@ -11,19 +13,19 @@ function writeConfigFile() {
write; write;
if (!templateExists) { if (!templateExists) {
throw new Error('Could not locate a configuration file. Please check your deployment for config.js or config.example.js.'); return errors.logError(new Error('Could not locate a configuration file.'), process.cwd(), 'Please check your deployment for config.js or config.example.js.');
} }
// Copy config.example.js => config.js // Copy config.example.js => config.js
read = fs.createReadStream('config.example.js'); read = fs.createReadStream('config.example.js');
read.on('error', function (err) { read.on('error', function (err) {
throw new Error('Could not open config.example.js for read.'); return errors.logError(new Error('Could not open config.example.js for read.'), process.cwd(), 'Please check your deployment for config.js or config.example.js.');
}); });
read.on('end', written.resolve); read.on('end', written.resolve);
write = fs.createWriteStream('config.js'); write = fs.createWriteStream('config.js');
write.on('error', function (err) { write.on('error', function (err) {
throw new Error('Could not open config.js for write.'); return errors.logError(new Error('Could not open config.js for write.'), process.cwd(), 'Please check your deployment for config.js or config.example.js.');
}); });
read.pipe(write); read.pipe(write);
@ -32,15 +34,54 @@ function writeConfigFile() {
return written.promise; return written.promise;
} }
function validateConfigEnvironment() {
var envVal = process.env.NODE_ENV || 'undefined',
config,
parsedUrl;
try {
config = require('../config')[envVal];
} catch (ignore) {
}
// 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, 'Ensure your config.js has a section for the current NODE_ENV value');
return when.reject();
}
// Check that our url is valid
parsedUrl = url.parse(config.url || 'invalid');
if (!parsedUrl.protocol || !parsedUrl.host) {
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();
}
// Check that we have database values
if (!config.database) {
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();
}
// Check for valid server host and port values
if (!config.server || !config.server.host || !config.server.port) {
errors.logError(new Error('Your server values (host and port) in config.js are invalid.'), JSON.stringify(config.server), 'Please provide them before restarting.');
return when.reject();
}
return when.resolve();
}
exports.loadConfig = function () { exports.loadConfig = function () {
var loaded = when.defer(); var loaded = when.defer();
/* Check for config file and copy from config.example.js /* Check for config file and copy from config.example.js
if one doesn't exist. After that, start the server. */ if one doesn't exist. After that, start the server. */
fs.exists('config.js', function checkConfig(configExists) { fs.exists('config.js', function checkConfig(configExists) {
if (configExists) { if (configExists) {
loaded.resolve(); validateConfigEnvironment().then(loaded.resolve).otherwise(loaded.reject);
} else { } else {
writeConfigFile().then(loaded.resolve).otherwise(loaded.reject); writeConfigFile().then(validateConfigEnvironment).then(loaded.resolve).otherwise(loaded.reject);
} }
}); });
return loaded.promise; return loaded.promise;

View File

@ -130,14 +130,14 @@ Ghost.prototype.init = function () {
function doFirstRun() { function doFirstRun() {
var firstRunMessage = [ var firstRunMessage = [
"Welcome to Ghost.", 'Welcome to Ghost.',
"You're running under the <strong>", 'You\'re running under the <strong>',
process.env.NODE_ENV, process.env.NODE_ENV,
"</strong>environment.", '</strong>environment.',
"Your URL is set to", 'Your URL is set to',
"<strong>" + self.config().url + "</strong>.", '<strong>' + self.config().url + '</strong>.',
"See <a href=\"http://docs.ghost.org/\">http://docs.ghost.org</a> for instructions." 'See <a href="http://docs.ghost.org/">http://docs.ghost.org</a> for instructions.'
]; ];
self.notifications.push({ self.notifications.push({
@ -165,14 +165,13 @@ Ghost.prototype.init = function () {
} }
// ### Initialisation // ### Initialisation
// make sure things are done in order
return when.join( return when.join(
// Initialise the models // Initialise the models
instance.dataProvider.init(), self.dataProvider.init(),
// Calculate paths // Calculate paths
instance.getPaths(), self.getPaths(),
// Initialise mail after first run // Initialise mail after first run
instance.mail.init(self) self.mail.init(self)
).then(function () { ).then(function () {
// Populate any missing default settings // Populate any missing default settings
return models.Settings.populateDefaults(); return models.Settings.populateDefaults();

View File

@ -12,6 +12,7 @@ var testUtils = require('./testUtils'),
describe("Ghost API", function () { describe("Ghost API", function () {
var testTemplatePath = 'core/test/unit/fixtures/', var testTemplatePath = 'core/test/unit/fixtures/',
themeTemplatePath = 'core/test/unit/fixtures/theme', themeTemplatePath = 'core/test/unit/fixtures/theme',
sandbox,
ghost; ghost;
before(function (done) { before(function (done) {
@ -21,23 +22,26 @@ describe("Ghost API", function () {
}); });
beforeEach(function (done) { beforeEach(function (done) {
sandbox = sinon.sandbox.create();
testUtils.initData().then(function () { testUtils.initData().then(function () {
ghost = new Ghost(); ghost = new Ghost();
done(); done();
}, done); }, done);
}); });
it("is a singleton", function () { afterEach(function () {
var logStub = sinon.stub(console, "log"), sandbox.restore();
ghost1 = new Ghost(), });
ghost2 = new Ghost();
should.strictEqual(ghost1, ghost2); it("is a singleton", function () {
logStub.restore(); var ghost2 = new Ghost();
should.strictEqual(ghost, ghost2);
}); });
it("uses init() to initialize", function (done) { it("uses init() to initialize", function (done) {
var dataProviderInitMock = sinon.stub(ghost.dataProvider, "init", function () { var dataProviderInitMock = sandbox.stub(ghost.dataProvider, "init", function () {
return when.resolve(); return when.resolve();
}); });
@ -49,8 +53,6 @@ describe("Ghost API", function () {
dataProviderInitMock.called.should.equal(true); dataProviderInitMock.called.should.equal(true);
dataProviderInitMock.restore();
done(); done();
}, done); }, done);
@ -59,7 +61,7 @@ describe("Ghost API", function () {
it("can register filters with specific priority", function () { it("can register filters with specific priority", function () {
var filterName = 'test', var filterName = 'test',
filterPriority = 9, filterPriority = 9,
testFilterHandler = sinon.spy(); testFilterHandler = sandbox.spy();
ghost.registerFilter(filterName, filterPriority, testFilterHandler); ghost.registerFilter(filterName, filterPriority, testFilterHandler);
@ -72,7 +74,7 @@ describe("Ghost API", function () {
it("can register filters with default priority", function () { it("can register filters with default priority", function () {
var filterName = 'test', var filterName = 'test',
defaultPriority = 5, defaultPriority = 5,
testFilterHandler = sinon.spy(); testFilterHandler = sandbox.spy();
ghost.registerFilter(filterName, testFilterHandler); ghost.registerFilter(filterName, testFilterHandler);
@ -84,9 +86,9 @@ describe("Ghost API", function () {
it("executes filters in priority order", function (done) { it("executes filters in priority order", function (done) {
var filterName = 'testpriority', var filterName = 'testpriority',
testFilterHandler1 = sinon.spy(), testFilterHandler1 = sandbox.spy(),
testFilterHandler2 = sinon.spy(), testFilterHandler2 = sandbox.spy(),
testFilterHandler3 = sinon.spy(); testFilterHandler3 = sandbox.spy();
ghost.registerFilter(filterName, 0, testFilterHandler1); ghost.registerFilter(filterName, 0, testFilterHandler1);
ghost.registerFilter(filterName, 2, testFilterHandler2); ghost.registerFilter(filterName, 2, testFilterHandler2);
@ -118,13 +120,13 @@ describe("Ghost API", function () {
}); });
it("loads templates for helpers", function (done) { it("loads templates for helpers", function (done) {
var compileSpy = sinon.spy(ghost, 'compileTemplate'), var compileSpy = sandbox.spy(ghost, 'compileTemplate'),
pathsStub; pathsStub;
should.exist(ghost.loadTemplate, 'load template function exists'); should.exist(ghost.loadTemplate, 'load template function exists');
// In order for the test to work, need to replace the path to the template // In order for the test to work, need to replace the path to the template
pathsStub = sinon.stub(ghost, "paths", function () { pathsStub = sandbox.stub(ghost, "paths", function () {
return { return {
// Forcing the theme path to be the same // Forcing the theme path to be the same
activeTheme: path.join(process.cwd(), testTemplatePath), activeTheme: path.join(process.cwd(), testTemplatePath),
@ -145,20 +147,18 @@ describe("Ghost API", function () {
templateFn().should.equal('<h1>HelloWorld</h1>'); templateFn().should.equal('<h1>HelloWorld</h1>');
done(); done();
}).then(null, done); }).then(null, done);
}); });
it("loads templates from themes first", function (done) { it("loads templates from themes first", function (done) {
var compileSpy = sinon.spy(ghost, 'compileTemplate'), var compileSpy = sandbox.spy(ghost, 'compileTemplate'),
pathsStub; pathsStub;
should.exist(ghost.loadTemplate, 'load template function exists'); should.exist(ghost.loadTemplate, 'load template function exists');
// In order for the test to work, need to replace the path to the template // In order for the test to work, need to replace the path to the template
pathsStub = sinon.stub(ghost, "paths", function () { pathsStub = sandbox.stub(ghost, "paths", function () {
return { return {
activeTheme: path.join(process.cwd(), themeTemplatePath), activeTheme: path.join(process.cwd(), themeTemplatePath),
helperTemplates: path.join(process.cwd(), testTemplatePath) helperTemplates: path.join(process.cwd(), testTemplatePath)