uglify在运行child_process.execFile后崩溃

编辑2

我“解决了”这个问题,但是我不想把它作为答案,它不能解释实际发生的事情。 在我使用的.NET resourceReader.exe的代码中

 Console.OutputEncoding = System.Text.Encoding.UTF8; 

将国际化的资源stdout到unicode的stdout 。 如果我重置编码在我的程序结束

 Console.OutputEncoding = System.Text.Encoding.Default; 

那么我在Node中没有任何错误。 如果我没有重置它,我会得到原始问题中描述的错误。 看来,.NET在某种程度上弄乱了cmd.exe上的一些输出编码设置,导致后续节点运行失败!

编辑

我缩小了由resourceReader.exe引起的错误。 这是一个.NET程序,它从.NET程序集中读取一些资源stream,并使用Console.WriteLine它们打印到stdout。 我将Console.OutputEncoding = System.Text.Encoding.UTF8添加到resourceReader.exe因为有些资源是非ASCII字母的,这就是导致崩溃的原因!

如果我把这条线取出来,任务不会崩溃,但资源显示为不可打印的ASCII字符! 另外,崩溃只发生,如果我真的打印非ASCII到sdtout。 如果我不打印它们,它不会出错。

原版的

我添加了一个步骤到我的Gruntfile使用child_process.execFile运行从外部程序读取一些数据,并在构build中使用它。 现在每当我运行我的构build,它第一次运行良好,但第二次崩溃!

这里是崩溃的输出(这是在uglify任务):

 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) 

这是使用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; } 

这里有一些我发现的debugging可能会有所帮助

  1. 如果我redirectgrunt的输出(使用> filename| process )它运行良好
  2. 当我redirect输出, 我从来没有看到uglify的消息,它创build的主要输出只是它创build源地图。
  3. 如果我closures并重新打开我的命令提示符( cmd.exe ),它工作正常
  4. 我使用rdr.on("close", function() { console.log("close"); });添加了一个监听器来监听subprocess的exitclose事件rdr.on("close", function() { console.log("close"); }); 和退出一样。 这两起事件都是在第一轮中按预期发生的。
  5. 使用Process Explorer,我可以在命令提示符下看到node.exe打开,并在命令结束运行时再次closures。 在命令提示符下没有任何进程明显“打开”。

堆栈跟踪最终显示一个socket.write错误的socket.write是有趣的。 您提供的代码中没有任何内容表明您正在尝试写入套接字。

如果我们沿着堆栈向下,我们可以看到,试图写入套接字实际上是一团糟,因为它试图logging未捕获的exception。

所以,首先你的咕噜任务抛出一个当前未知的错误,然后咕噜自己的错误,因为它不能告诉你。

我会先尝试logging在你的subprocess中发生的错误。 目前,如果出现错误,您只需简单地throw它,而不会发现它是什么。 这很可能是这个咕噜咕噜地尝试并且没有logging的东西。

更换

if (err) throw new Error(err);

if (err) console.error(err);

这将有希望避免socket.write问题,并给你有关在subprocess上发生什么错误的具体信息。 你看到了什么?

其次,我会尝试使用child_process.exec而不是child_process.execFile 。 这将产生一个shell并运行其中的resourceReader.exe (而不是直接运行)。 这可能有助于避免遇到在后台运行/失败的命令遇到的任何问题,这可能是socket.write错误的原因。