Recently I find we can skip the finally {} block when we are inside a try{} block and without any error reported.
The shortest code is as the following:
async function main() {
try {
await new Promise(r => console.log('IN TRY BLOCK'))
} finally {
console.log('IN FINALLY BLOCK')
}
}
main()
After running the above program, it will exit immediately with the following one line output:
IN TRY BLOCK
If we echo $? we can get 0. The finally{} block has been skipped(which is unexpected).
After thinking/asking/thinking, I begin to understand the reason behind this, more details are in this StackOverflow question/answer: https://stackoverflow.com/questions/49728838/node-js-program-does-not-run-the-finally-block-after-try-and-exit-with/
However, I still feel there's something not right.
So I post this issue is want to know: do we think this behavior is right? I feel it is not expected because if we write a try {} finally {}, we will expect the finally {} block always be executed, if it is not at least should raise an error, and I believe the Java/C++ will all follow this flow.
Unresolved promises do not keep a process alive. In this case, main function returns a Promise which is paused at the await statement. The finally cannot execute until await is done waiting on the promise to resolve.
You could also think of the code in your example in slightly different terms:
function main() {
return new Promise(() => console.log('IN TRY BLOCK'))
.finally(() => console.log('IN FINALLY BLOCK'));
}
main();
(This is actually not quite correct as there should be a nested Promise but then reasoning about it becomes a pain.)
In general, I recommend https://github.com/nodejs/help/issues for these types of questions. This tracker is for Node.js core issues or bugs only.
@apapirovski Thanks for the reply.
I can understand that the finally{} block will not be executed because of unresolved promises do not keep a process alive in Node.js.
However, my question is: should we keep the try {} finally {} behavior consistent with Java & C++ ?
Because this behavior of the try {} finally {} statement in Node.js will make the people who are familiar with Java & C++ very confusing.
@zixia This isn't really a Node.js issue, it's a language issue (EcmaScript) and I can't imagine it will change given that it would break the entirety of the rest of the JavaScript ecosystem.
Yes, I agree with you that it's not a Node.js issue but an ES language issue.
Thank you very much!
However, my question is: should we keep the try {} finally {} behavior consistent with Java & C++ ?
If you want to think about this in C++ or Java terms, it's as if you sent the thread a SIGSTOP signal right after printing the message and then never unpause it again. They won't execute the finally block in that case either.
@bnoordhuis Brilliant! :+1:
I feel better about this Node.js behavior after your explanation: It's fair enough for the program languages when running on the operation system with some extreme conditions...
Most helpful comment
If you want to think about this in C++ or Java terms, it's as if you sent the thread a
SIGSTOPsignal right after printing the message and then never unpause it again. They won't execute thefinallyblock in that case either.