Reputation: 2200
The following code gives an UnhandledPromiseRejectionWarning for p2, despite errors on p2 being explicitly handled.
function syncFunctionReturnsPromise(val)
{
return new Promise((r,x)=> {
setTimeout(()=> {
if (val) {
r('ok');
} else {
x('not ok');
}
}, val?1000:500);
});
}
async function test(){
let p1 = syncFunctionReturnsPromise(true);
let p2 = syncFunctionReturnsPromise(false);
await p1.catch(ex => console.warn('warning:', ex)); //errors in these 2 promises
await p2.catch(ex => console.warn('warning:', ex)); //are not the end of the world
console.log('doOtherStuff');
}
test();
The output looks like this:
(node:9056) UnhandledPromiseRejectionWarning: not ok
(node:9056) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:9056) [DEP0018] 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.
warning: not ok
doOtherStuff
(node:9056) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
It is not immediately obvious to me why this should be
Upvotes: 3
Views: 697
Reputation: 1666
Here is the other way:
async function test(){
let p1 = await syncFunctionReturnsPromise(true)
.catch(ex => console.warn('warning:', ex));
let p2 = await syncFunctionReturnsPromise(false)
.catch(ex => console.warn('warning:', ex));
console.log('doOtherStuff');
}
Upvotes: 0
Reputation: 2200
So this is because the first await waits synchronously before the handler is attached to p2. But p2 fails before p1 completes.
So node detects that p2 failed without any error handling.
N.B. In later versions of node this may cause the program to terminate, rather than just a warning.
The fix is to attach the handlers before awaiting
async function test(){
let p1 = syncFunctionReturnsPromise(true);
let p2 = syncFunctionReturnsPromise(false);
p1 = p1.catch(ex => console.warn('warning:', ex)); //errors in these 2 promises
p2 = p2.catch(ex => console.warn('warning:', ex)); //are not the end of the world
await p1;
await p2;
console.log('doOtherStuff');
}
Obviously you could inline that on the declaration although in my realworld code its neater as separate lines.
Upvotes: 5