Do not call callbacks twice in async boot scripts

See #252 for details
This commit is contained in:
Jürg Lehni 2017-08-16 20:32:06 +02:00
parent fa656e4bee
commit c9a1e0cc69
3 changed files with 32 additions and 2 deletions

View File

@ -306,11 +306,11 @@ function runScripts(app, list, callback) {
async.eachSeries(functions, function(f, done) {
debug('Running script %s', f.path);
var cb = function(err) {
debug('Async function finished %s', f.path);
debug('Async function %s %s', err ? 'failed' : 'finished', f.path);
done(err);
// Make sure done() isn't called twice, e.g. if a script returns a
// thenable object and also calls the passed callback.
cb = null;
cb = function() {};
};
try {
var result = f.func(app, cb);

View File

@ -373,6 +373,23 @@ describe('executor', function() {
});
});
describe('with boot script returning a promise and calling callback',
function() {
before(function() {
process.promiseAndCallback = true;
});
after(function() {
delete process.promiseAndCallback;
});
it('should only call the callback once', function(done) {
// Note: Mocha will fail this test if done() is called twice
boot.execute(app, simpleAppInstructions(), done);
});
}
);
describe('for mixins', function() {
var options;
beforeEach(function() {

View File

@ -0,0 +1,13 @@
// Copyright IBM Corp. 2017. All Rights Reserved.
// Node module: loopback-boot
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
var Promise = require('bluebird');
module.exports = function(app, callback) {
callback();
if (process.promiseAndCallback) {
return Promise.reject();
}
};