Skip to content

Commit 09fdf72

Browse files
author
Tom Kirkpatrick
committed
fix: ensure errors are properly logged
1 parent 722cab5 commit 09fdf72

File tree

7 files changed

+71
-81
lines changed

7 files changed

+71
-81
lines changed

lib/models/migration.js

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ module.exports = function(Migration, options) {
6363
assert(typeof cb === 'function', 'The cb argument must be a function, not ' + typeof cb);
6464

6565
if (Migration.app.migrating) {
66-
Migration.log.warn('Unable to start migration: already running');
66+
Migration.log.warn('Migration: Unable to start migration (already running)');
6767
process.nextTick(function() {
6868
cb();
6969
});
@@ -73,26 +73,22 @@ module.exports = function(Migration, options) {
7373
Migration.hrstart = process.hrtime();
7474
Migration.app.migrating = true;
7575

76-
Migration.log.info(name, 'running.');
76+
Migration.log.info('Migration: running script', name);
7777
const scriptPath = path.resolve(path.join(Migration.migrationsDir, name));
7878

7979
try {
8080
require(scriptPath).up(Migration.app, function(err) {
81-
if (err) {
82-
Migration.log.error(`Error running migration script ${name}:`, err);
83-
Migration.finish(err);
84-
return cb(err);
85-
} else if (record) {
81+
if (record) {
8682
Migration.create({
8783
name: name,
8884
runDtTm: new Date()
8985
});
9086
}
91-
Migration.finish();
92-
cb();
87+
Migration.finish(err);
88+
return cb();
9389
});
9490
} catch (err) {
95-
Migration.log.error(`Error running migration script ${name}:`, err);
91+
Migration.log.error(`Migration: Error running script ${name}:`, err);
9692
Migration.finish(err);
9793
cb(err);
9894
}
@@ -123,7 +119,7 @@ module.exports = function(Migration, options) {
123119
assert(typeof cb === 'function', 'The cb argument must be a function, not ' + typeof cb);
124120

125121
if (Migration.app.migrating) {
126-
Migration.log.warn('Unable to start migrations: already running');
122+
Migration.log.warn('Migration: Unable to start migrations (already running)');
127123
process.nextTick(function() {
128124
cb();
129125
});
@@ -139,7 +135,7 @@ module.exports = function(Migration, options) {
139135
var migrationCallIndex = 0;
140136

141137
if (scriptsToRun.length) {
142-
Migration.log.info('Running migrations: \n', scriptsToRun);
138+
Migration.log.info('Migration: Running migration scripts', scriptsToRun);
143139
}
144140

145141
scriptsToRun.forEach(function(localScriptName) {
@@ -150,33 +146,30 @@ module.exports = function(Migration, options) {
150146
// keep calling scripts recursively until we are done, then exit
151147
function runNextScript(err) {
152148
if (err) {
153-
Migration.log.error('Error saving migration', localScriptName, 'to database!');
154-
Migration.log.error(err);
149+
Migration.log.error('Migration: Error saving migration %s to database', localScriptName);
155150
Migration.finish(err);
156151
return cb(err);
157152
}
158153

159154
var migrationEndTime = process.hrtime(migrationStartTime);
160-
Migration.log.info('%s finished sucessfully. Migration time was %ds %dms',
155+
Migration.log.info('Migration: %s finished sucessfully. Migration time was %ds %dms',
161156
localScriptName, migrationEndTime[0], migrationEndTime[1] / 1000000);
162157
migrationCallIndex++;
163158
if (migrationCallIndex < migrationCallStack.length) {
164159
migrationCallStack[migrationCallIndex]();
165160
} else {
166-
Migration.finish();
161+
Migration.finish(err);
167162
return cb();
168163
}
169164
}
170165

171166
try {
172167
// include the script, run the up/down function, update the migrations table, and continue
173168
migrationStartTime = process.hrtime();
174-
Migration.log.info(localScriptName, 'running.');
169+
Migration.log.info('Migration: Running script', localScriptName);
175170
const scriptPath = path.resolve(path.join(Migration.migrationsDir, localScriptName));
176171
require(scriptPath)[upOrDown](Migration.app, function(err) {
177172
if (err) {
178-
Migration.log.error(localScriptName, 'error:');
179-
Migration.log.error(err.stack);
180173
Migration.finish(err);
181174
return cb(err);
182175
} else if (upOrDown === 'up') {
@@ -191,8 +184,6 @@ module.exports = function(Migration, options) {
191184
}
192185
});
193186
} catch (err) {
194-
Migration.log.error('Error running migration', localScriptName);
195-
Migration.log.error(err.stack);
196187
Migration.finish(err);
197188
cb(err);
198189
}
@@ -205,7 +196,7 @@ module.exports = function(Migration, options) {
205196
} else {
206197
delete Migration.app.migrating;
207198
Migration.emit('complete');
208-
Migration.log.info('No new migrations to run.');
199+
Migration.log.info('Migration: No new migrations to run.');
209200
return cb();
210201
}
211202
});
@@ -215,15 +206,10 @@ module.exports = function(Migration, options) {
215206

216207
Migration.finish = function(err) {
217208
if (err) {
218-
Migration.log.error('Migrations did not complete. An error was encountered:', err);
219209
Migration.emit('error', err);
220210
} else {
221-
Migration.log.info('All migrations have run without any errors.');
222211
Migration.emit('complete');
223212
}
224-
delete Migration.app.migrating;
225-
var hrend = process.hrtime(Migration.hrstart);
226-
Migration.log.info('Total migration time was %ds %dms', hrend[0], hrend[1] / 1000000);
227213
};
228214

229215
Migration.findScriptsToRun = function(upOrDown, to, cb) {
@@ -321,8 +307,7 @@ module.exports = function(Migration, options) {
321307
}
322308
})
323309
.catch(function(err) {
324-
Migration.log.error('Error retrieving migrations:');
325-
Migration.log.error(err.stack);
310+
Migration.log.error('Migration: Error retrieving migrations', err);
326311
cb(err);
327312
});
328313

@@ -333,5 +318,17 @@ module.exports = function(Migration, options) {
333318
return scriptObj.name;
334319
};
335320

321+
Migration.on('error', (err) => {
322+
Migration.log.error('Migration: Migrations did not complete. An error was encountered:', err);
323+
delete Migration.app.migrating;
324+
});
325+
326+
Migration.on('complete', (err) => {
327+
var hrend = process.hrtime(Migration.hrstart);
328+
Migration.log.info('Migration: All migrations have run without any errors.');
329+
Migration.log.info('Migration: Total migration time was %ds %dms', hrend[0], hrend[1] / 1000000);
330+
delete Migration.app.migrating;
331+
});
332+
336333
return Migration;
337334
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
"loopback": ">=2.22.0"
5757
},
5858
"devDependencies": {
59-
"bluebird": "latest",
59+
"bluebird": "^3.5.0",
6060
"chai": "latest",
6161
"condition-circle": "^1.5.0",
6262
"ghooks": "^1.3.2",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"../../../../lib": {
3+
"enableRest": false,
4+
"migrationsDir": "./test/fixtures/simple-app/server/migrations"
5+
}
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module.exports = {
2+
up: function(dataSource, next) {
3+
process.nextTick(() => next(new Error('some error in up')))
4+
},
5+
down: function(dataSource, next) {
6+
process.nextTick(() => next())
7+
}
8+
};

test/fixtures/simple-app/server/model-config.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
"_meta": {
33
"sources": [
44
"../common/models"
5-
],
6-
"mixins": [
7-
"../../../../"
85
]
96
},
107
"User": {

test/fixtures/simple-app/server/server.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,6 @@ app.start = function() {
2121
boot(app, __dirname, function(err) {
2222
if (err) throw err;
2323

24-
var migrate = require(path.join(__dirname, '..', '..', '..', '..', 'lib'));
25-
var options = {
26-
// dataSource: ds, // Data source for migrate data persistence,
27-
migrationsDir: path.join(__dirname, 'migrations'), // Migrations directory.
28-
enableRest: true
29-
};
30-
migrate(
31-
app, // The app instance
32-
options // The options
33-
);
34-
3524
// Register explorer using component-centric API:
3625
explorer(app, { basePath: '/api', mountPath: '/explorer' });
3726

test/test.js

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,17 @@ describe('loopback db migrate', function() {
7474
});
7575

7676
// Delete all data after each test.
77-
beforeEach(function(done) {
78-
Promise.all([
77+
beforeEach(function() {
78+
return Promise.all([
7979
app.models.Migration.destroyAll(),
8080
app.models.Migration.destroyAll()
8181
])
8282
.then(function() {
83-
done();
83+
return app.models.Migration.create({
84+
name: '0000-error.js',
85+
runDtTm: new Date()
86+
})
8487
})
85-
.catch(done);
8688
});
8789

8890
describe('migrateByName', function() {
@@ -97,50 +99,51 @@ describe('loopback db migrate', function() {
9799
})
98100
.catch(done);
99101
});
100-
});
101102

103+
it('should log errors', function() {
104+
return app.models.Migration.migrateByName('0000-error.js')
105+
.catch(function(err) {
106+
expect(err).to.not.be.undefined;
107+
})
108+
});
109+
110+
});
102111
describe('migrate', function() {
103-
it('should set a property on app to indicate that migrations are running', function(done) {
112+
it('should set a property on app to indicate that migrations are running', function() {
104113
var self = this;
105114
expect(app.migrating).to.be.undefined;
106115
var promise = app.models.Migration.migrate();
107116
expect(app.migrating).to.be.true;
108-
promise.then(function() {
117+
return promise.then(function() {
109118
expect(app.migrating).to.be.undefined;
110-
done();
111119
})
112-
.catch(done);
113120
});
114121
});
115122

116123
describe('up', function() {
117-
it('should run all migration scripts', function(done) {
124+
it('should run all migration scripts', function() {
118125
var self = this;
119-
app.models.Migration.migrate()
126+
return app.models.Migration.migrate()
120127
.then(function() {
121128
expect(self.spies.m1Up).to.have.been.called;
122129
expect(self.spies.m2Up).to.have.been.calledAfter(self.spies.m1Up);
123130
expect(self.spies.m3Up).to.have.been.calledAfter(self.spies.m2Up);
124131
self.expectNoDown();
125-
done();
126132
})
127-
.catch(done);
128133
});
129-
it('should run migrations up to the specificed point only', function(done) {
134+
it('should run migrations up to the specificed point only', function() {
130135
var self = this;
131-
app.models.Migration.migrate('up', '0002-somechanges')
136+
return app.models.Migration.migrate('up', '0002-somechanges')
132137
.then(function() {
133138
expect(self.spies.m1Up).to.have.been.calledBefore(self.spies.m2Up);
134139
expect(self.spies.m2Up).to.have.been.calledAfter(self.spies.m1Up);
135140
expect(self.spies.m3Up).not.to.have.been.called;
136141
self.expectNoDown();
137-
done();
138142
})
139-
.catch(done);
140143
});
141-
it('should not rerun migrations that hae already been run', function(done) {
144+
it('should not rerun migrations that hae already been run', function() {
142145
var self = this;
143-
app.models.Migration.migrate('up', '0002-somechanges')
146+
return app.models.Migration.migrate('up', '0002-somechanges')
144147
.then(function() {
145148
self.resetSpies();
146149
return app.models.Migration.migrate('up');
@@ -150,16 +153,14 @@ describe('loopback db migrate', function() {
150153
expect(self.spies.m2Up).not.to.have.been.called;
151154
expect(self.spies.m3Up).to.have.been.called;
152155
self.expectNoDown();
153-
done();
154156
})
155-
.catch(done);
156157
});
157158
});
158159

159160
describe('down', function() {
160-
it('should run all rollback scripts in reverse order', function(done) {
161+
it('should run all rollback scripts in reverse order', function() {
161162
var self = this;
162-
app.models.Migration.migrate('up')
163+
return app.models.Migration.migrate('up')
163164
.then(function() {
164165
self.expectNoDown();
165166
self.resetSpies();
@@ -170,13 +171,11 @@ describe('loopback db migrate', function() {
170171
expect(self.spies.m2Down).to.have.been.calledAfter(self.spies.m3Down);
171172
expect(self.spies.m1Down).to.have.been.calledAfter(self.spies.m2Down);
172173
self.expectNoUp();
173-
done();
174174
})
175-
.catch(done);
176175
});
177-
it('should run rollbacks up to the specificed point only', function(done) {
176+
it('should run rollbacks up to the specificed point only', function() {
178177
var self = this;
179-
app.models.Migration.migrate('up')
178+
return app.models.Migration.migrate('up')
180179
.then(function() {
181180
self.expectNoDown();
182181
self.resetSpies();
@@ -187,13 +186,11 @@ describe('loopback db migrate', function() {
187186
expect(self.spies.m2Down).to.have.been.calledAfter(self.spies.m3Down);
188187
expect(self.spies.m1Down).not.to.have.been.called;
189188
self.expectNoUp();
190-
done();
191189
})
192-
.catch(done);
193190
});
194-
it('should not rerun rollbacks that hae already been run', function(done) {
191+
it('should not rerun rollbacks that hae already been run', function() {
195192
var self = this;
196-
app.models.Migration.migrate('up')
193+
return app.models.Migration.migrate('up')
197194
.then(function() {
198195
return app.models.Migration.migrate('down', '0001-initialize');
199196
})
@@ -206,13 +203,11 @@ describe('loopback db migrate', function() {
206203
expect(self.spies.m2Down).to.not.have.been.called;
207204
expect(self.spies.m1Down).to.have.been.called;
208205
self.expectNoUp();
209-
done();
210206
})
211-
.catch(done);
212207
});
213-
it('should rollback a single migration that has not already run', function(done) {
208+
it('should rollback a single migration that has not already run', function() {
214209
var self = this;
215-
app.models.Migration.migrate('up', '0002-somechanges')
210+
return app.models.Migration.migrate('up', '0002-somechanges')
216211
.then(function() {
217212
self.resetSpies();
218213
return app.models.Migration.migrate('down', '0003-morechanges');
@@ -222,9 +217,7 @@ describe('loopback db migrate', function() {
222217
expect(self.spies.m2Down).to.not.have.been.called;
223218
expect(self.spies.m1Down).to.not.have.been.called;
224219
self.expectNoUp();
225-
done();
226220
})
227-
.catch(done);
228221
});
229222
});
230223
});

0 commit comments

Comments
 (0)