Hey,
I recently experienced an issue, when registering plugins using promise style and the plugin itself is not calling next with a proper Error Object. (Btw. I'm using the latest hapi version 15.2.0.)
Let's say I'm registering plugins like this
server.on('start', () => console.log('server started successfully'));
return server.register(plugins) // plugins is a list of plugins
.then(() => server)
.catch((err) => {
console.errror('could not register plugins', err);
process.exit(1);
})
now imagine a bad plugin like this:
class BadError {
constructor(message) {
this.message = message;
}
}
const badPlugin = {
register(server, options, next) {
return next(new BadError('bad-error'));
}
};
badPlugin.register.attributes = { name: 'bad-plugin' };
and my list of plugins:
const plugins = [
/* .. `set-of-plugins-1` */,
{ register: badPlugin },
/* .. `set-of-plugins-2` */
]
What I thought is, that the server exits with code 1, but what happens is the server starts, logs server started successfully. Now the server keeps running and all set-of-plugins-1 are running but none of set-of-plugins-2.
I checked the code and what I can tell is, that when calling the server.register function without a callback it's using the Promise.wrap, which re-calls the function with a callback. The register function now iterates through all plugins using Items.serial, which itself breaks the serial flow whenever any argument is passed to the next callback. But now this "wrapped" promise callback only expects one argument, which if an Error is rejected otherwise resolved.
In the described case, the plugin is unfortunately not calling next with a proper Error Object. Now the Items.serials breaks the flow, it calls the wrapped promise callback, but this callback itself doesn't recognise the error and instead just resolves the Promise. In my case this leads to a situation where all plugins before the "bad" one are registered fine, but the rest not and the server keeps running.
In this case I'm not controlling the errors, but I could check the error and wrap it into a real Error Object. Another solution could be to check in the server.register().then() if any argument is passed to the then function it can only be an error (i think).
Of course it would be great if from hapi itself this would be reported as an error, maybe there should be a 4th argument to Promise.wrap (e.g. nodeStyleCallback = false) which if a first argument is given rejects and otherwise resolves with the second argument, because in the case of the plugin registration always only an error (or nothing) is passed to the callback, but of course i'm not super deeply into the code, so this is just an idea.
Thanks for reading.
Hey,
I recently experienced an issue, when registering plugins using promise style and the plugin itself is not calling next with a proper Error Object. (Btw. I'm using the latest hapi version 15.2.0.)
Let's say I'm registering plugins like this
now imagine a bad plugin like this:
and my list of plugins:
What I thought is, that the server exits with code
1, but what happens is the server starts, logsserver started successfully. Now the server keeps running and allset-of-plugins-1are running but none ofset-of-plugins-2.I checked the code and what I can tell is, that when calling the
server.registerfunction without a callback it's using thePromise.wrap, which re-calls the function with a callback. The register function now iterates through all plugins usingItems.serial, which itself breaks the serial flow whenever any argument is passed to the next callback. But now this "wrapped" promise callback only expects one argument, which if anErroris rejected otherwise resolved.In the described case, the plugin is unfortunately not calling next with a proper Error Object. Now the Items.serials breaks the flow, it calls the wrapped promise callback, but this callback itself doesn't recognise the error and instead just resolves the Promise. In my case this leads to a situation where all plugins before the "bad" one are registered fine, but the rest not and the server keeps running.
In this case I'm not controlling the errors, but I could check the error and wrap it into a real Error Object. Another solution could be to check in the
server.register().then()if any argument is passed to thethenfunction it can only be an error (i think).Of course it would be great if from hapi itself this would be reported as an error, maybe there should be a 4th argument to
Promise.wrap(e.g.nodeStyleCallback = false) which if a first argument is given rejects and otherwise resolves with the second argument, because in the case of the plugin registration always only an error (or nothing) is passed to the callback, but of course i'm not super deeply into the code, so this is just an idea.Thanks for reading.