EDIT 2
I "solved" the problem, but I don't want to post it as an answer b/c it doesn't explain what actually happened. In the code for the .NET resourceReader.exe
I use
Console.OutputEncoding = System.Text.Encoding.UTF8;
to output the internationalized resources to stdout
in unicode. If I reset the encoding at the end of my program with
Console.OutputEncoding = System.Text.Encoding.Default;
then I don't get any errors in Node. If I don't reset it, I get the error described in the original question. It seems that .NET is somehow messing up some of the output encoding settings on the cmd.exe
and causing the subsequent node run to fail!
EDIT
I narrowed down the error to being caused by resourceReader.exe
. It's a.NET program which reads some resource streams out of the .NET assembly and prints them to the stdout using Console.WriteLine
. I added Console.OutputEncoding = System.Text.Encoding.UTF8
to resourceReader.exe
because some of the resources are in non ASCII letters and that's whats causing the crash in grunt!
If I take that line out, the task doesn't crash, but the resources show up in non printable ASCII characters! Also, the crash only happens if I actually print non-ASCII to sdtout. If I don't print them, it doesn't error.
ORIGINAL
I added a step to my Gruntfile which uses child_process.execFile
to run an read some data from an external program and uses it in the build. Now whenever I run my build, it runs fine the first time, but crashes the second time!
Here's the output from the crash (this is during the uglify task):
File build/Scripts/NDB.contacts.min.js created: 16.85 kBevents.js:85
throw er; // Unhandled 'error' event
^
Error: This socket is closed.
at WriteStream.Socket._writeGeneric (net.js:656:19)
at WriteStream.Socket._write (net.js:709:8)
at doWrite (_stream_writable.js:301:12)
at writeOrBuffer (_stream_writable.js:288:5)
at WriteStream.Writable.write (_stream_writable.js:217:11)
at WriteStream.Socket.write (net.js:634:40)
at Log._write (C:\...\node_modules\grunt\node_modules\grunt-legacy-log\index.js:161:26)
at Log.wrapper [as _write] (C:\...\node_modules\grunt\node_modules\grunt-legacy-log\node_modules\lodash\index.js:3095:19)
at Log._writeln (C:\...\node_modules\grunt\node_modules\grunt-legacy-log\index.js:166:8)
at Log.wrapper [as _writeln] (C:\...\node_modules\grunt\node_modules\grunt-legacy-log\node_modules\lodash\index.js:3095:19)
at Log.writeln (C:\...\node_modules\grunt\node_modules\grunt-legacy-log\index.js:177:8)
at Log.wrapper (C:\...\node_modules\grunt\node_modules\grunt-legacy-log\node_modules\lodash\index.js:3095:19)
at writeln (C:\...\node_modules\grunt\lib\grunt\fail.js:30:13)
at Object.fail.fatal (C:\...\node_modules\grunt\lib\grunt\fail.js:46:3)
at process.uncaughtHandler (C:\...\node_modules\grunt\lib\grunt.js:121:10)
at process.emit (events.js:129:20)
at process._fatalException (node.js:236:26)
at Task.runTaskFn (C:\...\node_modules\grunt\lib\util\task.js:250:7)
at Task.<anonymous> (C:\...\node_modules\grunt\lib\util\task.js:293:12)
at C:\...\node_modules\grunt\lib\util\task.js:220:11
at process._tickCallback (node.js:355:11)
Here's the code for the task which uses child_process.
function readAllCultures() {
var readDeferred = q.defer();
childProc.execFile("../tools/resourceReader.exe", function (err, stdout, stderr) {
if (err) throw new Error(err);
var cultures = JSON.parse(stdout);
readDeferred.resolve(cultures);
});
return readDeferred.promise;
}
Here's some things I discovered debugging that might be helpful
- If I redirect the output of grunt (using either
> filename
or| process
) it runs fine - When I redirect output, I never see the message from uglify that it created the main output only that it created the source map.
- If I close and reopen my command prompt (
cmd.exe
) it works fine - I added a listener to the
exit
andclose
events of the child process usingrdr.on("close", function() { console.log("close"); });
and the same for exit. Both events fire as expected in the first run. - Using Process Explorer, I can see
node.exe
open under the command prompt and close again when my command finishes running. There are no processes visibly "left open" under the command prompt.
return readDeferred.reject()
than throwing from callback handler. – Crosscountry