In Node.js I have a module which consists of just one function. The function returns promise and the promise could be rejected. Still I don't want to force all users of the module to handle the rejection explicitly. By design in some cases it makes sense to just ignore the returned promise. Also I don't want to take the ability to handle the promise rejection away from module users.
What is the way to properly do so?
After upgrading to Node.js 7.1.0 all my unit tests which ignore rejection handling show the following warning:
(node:12732) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: try to throw an error from unit test
(node:12732) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
What is the proper way to prevent termination of Node.js process in the future mentioned in DeprecationWarning
description?
In general, using a custom library like bluebird you can suppress rejections just from your code but nowhere else. Native promises can't do this yet.
You can however manually suppress a promise by adding a catch handler for it.
function yourExportedFunction() {
const p = promiseThatMightRejectFn();
p.catch(() => {}); // add an empty catch handler
return p;
}
This way you are explicitly ignoring the rejection from the promise so it is no longer an unhandled rejection just a suppressed one.
If you're concerned about unhandled rejections causing your Nodejs process to terminate unintentionally in the future, you could register an event handler for the 'unhandledRejection' event on the process
object.
process.on('unhandledRejection', (err, p) => {
console.log('An unhandledRejection occurred');
console.log(`Rejected Promise: ${p}`);
console.log(`Rejection: ${err}`);
});
Edit
If you want the implementing user of your module to decide whether or not to handle the error in their code, you should just return your promise to the caller.
yourModule.js
function increment(value) {
return new Promise((resolve, reject) => {
if (!value)
return reject(new Error('a value to increment is required'));
return resolve(value++);
});
}
theirModule.js
const increment = require('./yourModule.js');
increment()
.then((incremented) => {
console.log(`Value incremented to ${incremented}`);
})
.catch((err) => {
// Handle rejections returned from increment()
console.log(err);
});
This is not your problem to fix.
Just use promises the way they were intended. If the end user doesn't want to handle all rejections then THEY have to add an unhandledRejection
handler. Otherwise they will need to add catches.
If your errors truly aren't breaking then you shouldn't be rejecting on them. Just resolve with an error value. e.g:
Success: resolve({result, error:null})
Failure: resolve({result:null, error})
It's still better to just reject and leave the end user to decide how to handle it.
I can't figure out any way to do what you're describing.
If you don't care about passing errors to your users, you can add a dummy catch
block on the end of your promise chain:
Promise.reject('foo')
.catch(() => {})
This will silence the warning, but won't allow your users to handle the error.
Perhaps you could add an option that your users could decide if they want to handle the error or not.