diff --git a/src/plugins/hooks.js b/src/plugins/hooks.js index f14c94791f..59f904d186 100644 --- a/src/plugins/hooks.js +++ b/src/plugins/hooks.js @@ -128,19 +128,28 @@ async function fireFilterHook(hook, hookList, params) { return await hookObj.method(params); } return new Promise((resolve, reject) => { + let resolved = false; + function _resolve(result) { + if (resolved) { + winston.warn(`[plugins] ${hook} already resolved in plugin ${hookObj.id}`); + return; + } + resolved = true; + resolve(result); + } const returned = hookObj.method(params, (err, result) => { - if (err) reject(err); else resolve(result); + if (err) reject(err); else _resolve(result); }); if (utils.isPromise(returned)) { returned.then( - payload => resolve(payload), + payload => _resolve(payload), err => reject(err) ); return; } if (returned) { - resolve(returned); + _resolve(returned); } }); } diff --git a/test/plugins.js b/test/plugins.js index b7b5575d28..ae5e403abf 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -71,6 +71,25 @@ describe('Plugins', () => { assert.strictEqual(data.foo, 8); }); + it('should not error with invalid hooks', async () => { + function method1(data, callback) { + data.foo += 1; + return data; + } + function method2(data, callback) { + data.foo += 2; + // this is invalid + callback(null, data); + return data; + } + + plugins.hooks.register('test-plugin', { hook: 'filter:test.hook3', method: method1 }); + plugins.hooks.register('test-plugin', { hook: 'filter:test.hook3', method: method2 }); + + const data = await plugins.hooks.fire('filter:test.hook3', { foo: 1 }); + assert.strictEqual(data.foo, 4); + }); + it('should register and fire a filter hook that returns a promise that gets rejected', (done) => { async function method(data) { return new Promise((resolve, reject) => { @@ -78,8 +97,8 @@ describe('Plugins', () => { reject(new Error('nope')); }); } - plugins.hooks.register('test-plugin', { hook: 'filter:test.hook3', method: method }); - plugins.hooks.fire('filter:test.hook3', { foo: 1 }, (err) => { + plugins.hooks.register('test-plugin', { hook: 'filter:test.hook4', method: method }); + plugins.hooks.fire('filter:test.hook4', { foo: 1 }, (err) => { assert(err); done(); });