mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-27 17:16:14 +01:00
feat: guard against multiple resolves
This commit is contained in:
@@ -128,19 +128,28 @@ async function fireFilterHook(hook, hookList, params) {
|
|||||||
return await hookObj.method(params);
|
return await hookObj.method(params);
|
||||||
}
|
}
|
||||||
return new Promise((resolve, reject) => {
|
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) => {
|
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)) {
|
if (utils.isPromise(returned)) {
|
||||||
returned.then(
|
returned.then(
|
||||||
payload => resolve(payload),
|
payload => _resolve(payload),
|
||||||
err => reject(err)
|
err => reject(err)
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (returned) {
|
if (returned) {
|
||||||
resolve(returned);
|
_resolve(returned);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,25 @@ describe('Plugins', () => {
|
|||||||
assert.strictEqual(data.foo, 8);
|
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) => {
|
it('should register and fire a filter hook that returns a promise that gets rejected', (done) => {
|
||||||
async function method(data) {
|
async function method(data) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -78,8 +97,8 @@ describe('Plugins', () => {
|
|||||||
reject(new Error('nope'));
|
reject(new Error('nope'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
plugins.hooks.register('test-plugin', { hook: 'filter:test.hook3', method: method });
|
plugins.hooks.register('test-plugin', { hook: 'filter:test.hook4', method: method });
|
||||||
plugins.hooks.fire('filter:test.hook3', { foo: 1 }, (err) => {
|
plugins.hooks.fire('filter:test.hook4', { foo: 1 }, (err) => {
|
||||||
assert(err);
|
assert(err);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user