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可能会有所帮助
- 如果我redirectgrunt的输出(使用
> filename
或| process
)它运行良好 - 当我redirect输出, 我从来没有看到uglify的消息,它创build的主要输出只是它创build源地图。
- 如果我closures并重新打开我的命令提示符(
cmd.exe
),它工作正常 - 我使用
rdr.on("close", function() { console.log("close"); });
添加了一个监听器来监听subprocess的exit
和close
事件rdr.on("close", function() { console.log("close"); });
和退出一样。 这两起事件都是在第一轮中按预期发生的。 - 使用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
错误的原因。