Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

console.error output not always flushed before process.exit #3479

Closed
clausreinke opened this issue Jun 18, 2012 · 7 comments
Closed

console.error output not always flushed before process.exit #3479

clausreinke opened this issue Jun 18, 2012 · 7 comments
Labels

Comments

@clausreinke
Copy link

I have a simple node script that uses exec to run node scripts.
After adding process.exit(1) calls to the child, its console.error output sometimes goes missing.

// -------------------------------- missing-stderr-output.js

function has(arg) { return (process.argv.indexOf(arg)>-1) }

if (has('child')) {

  // console.log('stdout');
  console.error('stderr');
  process.exit(1);

} else {

  var cmd = has('simple')
          ? 'cat nothing'
          : 'node missing-stderr-output.js child';

  require('child_process').exec(cmd
                               ,function(e,so,se){
                                  console.log(e);
                                  console.log(so);
                                  console.log(se);
                                })

}

Note that calling the child code directly shows the stderr output, while calling the
child via .exec loses the child's stderr output.

$ node --version
v0.6.19

$ node missing-stderr-output.js child
stderr

$ node missing-stderr-output.js
{ [Error: Command failed: ] killed: false, code: 1, signal: null }

Note that calling another failing sub-process does not lose stderr output:

$ node missing-stderr-output.js simple
{ [Error: Command failed: cat: nothing: No such file or directory
] killed: false, code: 1, signal: null }

cat: nothing: No such file or directory

Uncommenting the console.log line sometimes outputs both stdout and stderr, sometimes still none.

All of this is on windows, in an msys shell.

As a workaround, replacing

process.exit(1)

with

process.on('exit',function(){process.exit(1)});

seems to work.

@bnoordhuis
Copy link
Member

Seems to work for me. Can you retest it with v0.8?

By the way, it's better to use process.execPath instead of a hard-coded string 'node'.

@clausreinke
Copy link
Author

Have just installed and tried v0.8.0 (node --version result). Gives the same output (three empty lines after the Error: line). From cmd.exe:

C:\javascript\tst>node --version
v0.8.0

C:\javascript\tst>node missing-stderr-output.js child
stderr

C:\javascript\tst>node missing-stderr-output.js
{ [Error: Command failed: ] killed: false, code: 1, signal: null }



In the real code, the outer script is a test runner, which is why the 'node' was explicit. But you're right, if it is running, it doesn't need to test whether 'node' can be found:-)

@bnoordhuis
Copy link
Member

@piscisaureus You should probably look at this, I can't reproduce it.

@ghost
Copy link

ghost commented Jun 28, 2012

I get the same as @clausreinke with v0.8

@piscisaureus
Copy link

This is a particular behaviour of windows. When a pipe is closed all data that has been sent, but has not been read yet by the other end, is discarded. When a process exits it's pipe end is closed immediately. Normally libuv works around this issue, but when process.exit() is called libuv doesn't get the chance to do anything about it.

@piscisaureus
Copy link

Closing, tracking in #3584.

@clausreinke
Copy link
Author

Thanks for the info. So do I understand correctly that the data has been written, as far as the child process is concerned, but gets killed in transit when the child breaks the pipe on exit? Does that mean my workaround only works by accident, or does it profit from those libuv workarounds?

In any case, could this information be added to a portability issues section in the nodejs docs, with suggested workarounds?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants