21

I've made an node.js app to list all .txt files from a directory recursively and, for each one, do some stuff.

Here's my app.js:

var spawn = require('child_process').spawn,
    dir = spawn('dir', ['*.txt', '/b']);

dir.stdout.on('data', function (data) {
    //do some stuff with each stdout line...
    console.log('stdout: ' + data);
});

dir.stderr.on('data', function (data) {
    //throw errors
    console.log('stderr: ' + data);
});

dir.on('close', function (code) {
    console.log('child process exited with code ' + code);
});

When I run node app.js via console, I get the error message below:

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: spawn ENOENT
    at errnoException (child_process.js:980:11)
    at Process.ChildProcess._handle.onexit (child_process.js:771:34)

I'm using node v0.10.13 at win32 environment.

I do this way (spawn) because I want to handle stdout line by line (the exec method release entire stdout as one string).

* UPDATE *

By the way, using spawn for child_process does not guarantee that the output for cmd dir will be line by line. I've created a question for that too.

Community
  • 1
  • 1
tetri
  • 3,753
  • 2
  • 25
  • 37

2 Answers2

21

That happen because dir is not a executable in Windows. It's a command from the shell.
The solution for your problem is the following:

var dir = spawn('cmd', ['/c', 'dir']);
dir.stdout.on("data", function() {
    // do things
})

This exact problem was here also.

peller
  • 4,435
  • 19
  • 21
gustavohenke
  • 40,997
  • 14
  • 121
  • 129
  • 5
    I didn't downvote, but this answer doesn't really answer the question - where do we attach an on('error',fn) handler to capture the error (not just preventing the error!). – Alexander Mills Jun 13 '16 at 18:51
  • @AlexMills There isn't a real question here, there's no "?" :) And the `error` handler should be attached onto the spawned process. – gustavohenke Jun 21 '16 at 17:03
15

Several things:

  • dir is not a real executable in windows, so node.js cannot find the program you want to run.
  • You didn't bind an 'error' handler to your child process and the event was turned into an exception that crashed your node instance. Do this:
dir.on('error', function (err) {
  console.log('dir error', err);
});
  • Use fs.readdir instead. It's a standard node.js API that does the same thing.
Laurent Perrin
  • 14,671
  • 5
  • 50
  • 49