From 4d49d34712bf2d5bbd8732242511f17e83012df3 Mon Sep 17 00:00:00 2001 From: Lennart Kats Date: Wed, 4 Nov 2015 11:18:22 +0000 Subject: [PATCH] Fix vfs not always connecting if first node binary in list doesn't exist We'd first get a EPIPE and then an ENOENT in this scenario, breaking our retry behavior. --- node_modules/vfs-child/parent.js | 33 ++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/node_modules/vfs-child/parent.js b/node_modules/vfs-child/parent.js index cf6b53c5..f98d320c 100644 --- a/node_modules/vfs-child/parent.js +++ b/node_modules/vfs-child/parent.js @@ -1,6 +1,7 @@ var Consumer = require('vfs-socket/consumer').Consumer; var inherits = require('util').inherits; var spawn = require('child_process').spawn; +var fs = require("fs"); exports.Parent = Parent; @@ -23,27 +24,39 @@ function Parent(fsOptions) { // Override Consumer's connect since the transport logic is internal to this module this.connect = connect.bind(this); function connect(callback) { + var _self = this; try { + // Check if file exists first; spawn's ENOENT may arrive after other errors + if (!fs.existsSync(nodeBin[0])) + return tryNext(new Error("Couldn't find valid node binary")); child = spawn(nodeBin[0], args, options).on("error", tryNext); } catch (e) { - return tryNext(e); + return done(e); } child.stdin.readable = true; - Consumer.prototype.connect.call(this, [child.stdout, child.stdin], tryNext); + Consumer.prototype.connect.call(this, [child.stdout, child.stdin], done); child.on("exit", disconnect); child.stdin.resume(); - var _self = this; - // try all possible locations of node before giving up - function tryNext(err, vfs) { - if (!child) return; - child.removeListener("error", tryNext); - child.on("error", function ignore() {}); - if (err && err.code == "ENOENT" && nodeBin.length > 1) { - child = null; + + function tryNext(err) { + if (nodeBin.length > 1) { nodeBin.shift(); _self.emit("error", err); _self.connect(callback); + } else { + return done(err); + } + } + + function done(err, vfs) { + if (!child) return; + child.removeListener("error", done); + child.on("error", function ignore(err) {}); + child = null; + + if (err && err.code == "ENOENT") { + tryNext(err); } else { callback(err, vfs); }