Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A strange behavior of Node.js: program exit 0 inside try{} block without run finally {} block #19929

Closed
huan opened this issue Apr 11, 2018 · 8 comments
Labels
promises Issues and PRs related to ECMAScript promises. question Issues that look for answers.

Comments

@huan
Copy link

huan commented Apr 11, 2018

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.

@vsemozhetbyt vsemozhetbyt added question Issues that look for answers. v8 engine Issues and PRs related to the V8 dependency. promises Issues and PRs related to ECMAScript promises. labels Apr 11, 2018
@apapirovski
Copy link
Member

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.)

@apapirovski apapirovski removed the v8 engine Issues and PRs related to the V8 dependency. label Apr 11, 2018
@apapirovski
Copy link
Member

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
Copy link
Member

@huan
Copy link
Author

huan commented Apr 11, 2018

@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.

@apapirovski
Copy link
Member

@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.

@huan
Copy link
Author

huan commented Apr 11, 2018

Yes, I agree with you that it's not a Node.js issue but an ES language issue.

Thank you very much!

@bnoordhuis
Copy link
Member

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.

@huan
Copy link
Author

huan commented Apr 11, 2018

@bnoordhuis Brilliant! 👍

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...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
promises Issues and PRs related to ECMAScript promises. question Issues that look for answers.
Projects
None yet
Development

No branches or pull requests

4 participants