I have a node.js script like this (for educational purposes it’s entangled, not actual production code):
const run = new Promise((resolve, reject) => {
(async () => {
let cleanup = () => {
console.log('inside cleanup');
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, 5000);
});
};
try {
throw new Error('error');
} catch (err) {
console.log('rejecting')
reject(err);
} finally {
console.log('inside finally')
await cleanup().then(() => {
console.log('exiting');
resolve('done');
});
}
})();
});
run.then((r) => console.log(r));
Based on this answer, I would expect Node to wait and not exit until the promise inside finally
is resolved. However, it seems to exit immediately. What am I missing here?
$ node pup
rejecting
inside finally
inside cleanup
D:pup.js:16
throw new Error('error');
^
I might need to cleanup multiple resources in finally
in certain order, so I’d need to wait for completion of previous cleanup actions.
That’s the answer I was looking for:
You are already reject()ing the run promise before the finally block runs, causing an unhandled promise rejection that causes nodejs to exit.
2
Answers
The bit of the linked answer you appear to refer to is about (a) the promise returned from a function using the
async
keyword when (b) youawait
a promise inside atry
.You are doing neither.
You just call the
reject
callback insidecatch
. That’s for a promise that is completely independent of theasync
IIFE.By the time you call
resolve
you’ve already calledreject
.Avoid the
Promise
constructor antipattern! You are alreadyreject()
ing therun
promise before thefinally
block runs, causing an unhandled promise rejection that causes nodejs to exit.To fix this, use
You should avoid
return
ing from afinally
block as that would override the exception. If you actually meant to handle the error in thecatch
block, do not re-throw
it: