Handle errors in spawn

This commit is contained in:
Isaac Murchie
2014-01-24 10:43:17 -08:00
parent 1ce3ea2b6e
commit 5d7a543839
5 changed files with 54 additions and 21 deletions

View File

@@ -110,6 +110,9 @@ module.exports.runMochaTests = function (grunt, appName, testType, deviceType, c
var file = mochaFiles.shift();
if (typeof file !== "undefined") {
var mochaProc = spawn('mocha', args.concat(file), {cwd: __dirname});
mochaProc.on("error", function (err) {
grunt.fatal("Unable to spawn mocha process: mocha not installed?");
});
mochaProc.stdout.setEncoding('utf8');
mochaProc.stderr.setEncoding('utf8');
mochaProc.stdout.on('data', function (data) {
@@ -131,6 +134,9 @@ module.exports.runMochaTests = function (grunt, appName, testType, deviceType, c
module.exports.tail = function (grunt, filename, cb) {
var proc = spawn('tail', ['-f', filename]);
proc.on("error", function (err) {
grunt.fatal("Unable to spawn \"tail\": " + err.message);
});
proc.stdout.setEncoding('utf8');
proc.stdout.on('data', function (data) {
grunt.log.write(data);
@@ -239,6 +245,9 @@ module.exports.build = function (appRoot, cb, sdk, xcconfig) {
xcode = spawn('xcodebuild', args, {
cwd: appRoot
});
xcode.on("error", function (err) {
cb(new Error("Failed spawning xcodebuild: " + err.message));
});
var output = '';
var collect = function (data) { output += data; };
xcode.stdout.on('data', collect);
@@ -317,6 +326,9 @@ var setupAndroidProj = function (grunt, projPath, args, cb) {
grunt.fatal("The `android` command was not found at \"" + cmd + "\", are you sure ANDROID_HOME is set properly?");
}
var proc = spawn(cmd, args, {cwd: projPath});
proc.on("error", function (err) {
grunt.fatal("Unable to spawn android: " + err.message);
});
proc.stdout.setEncoding('utf8');
proc.stderr.setEncoding('utf8');
proc.stdout.on('data', function (data) {
@@ -361,8 +373,11 @@ var buildAndroidProj = function (grunt, projPath, target, cb) {
} else {
if (stdout) {
var cmd = stdout.split('\r\n')[0].trim();
grunt.log.write("Using " + cmdName + " found at " + cmd);
grunt.log.write("Using " + cmdName + " found at " + cmd + "\n");
var proc = spawn(cmd, [target], {cwd: projPath});
proc.on("error", function (err) {
grunt.fatal("Unable to spawn \"" + cmdName + "\"");
});
proc.stdout.setEncoding('utf8');
proc.stderr.setEncoding('utf8');
proc.stdout.on('data', function (data) {

View File

@@ -541,12 +541,12 @@ ADB.prototype.launchAVD = function (avdName, cb) {
avdName = "@" + avdName;
}
try {
spawn(emulatorBinaryPath.substr(1, emulatorBinaryPath.length - 2),
[avdName]);
} catch (err) {
return cb(err);
}
var proc = spawn(emulatorBinaryPath.substr(1, emulatorBinaryPath.length - 2),
[avdName]);
proc.on("error", function (err) {
logger.error("Unable to start Emulator: " + err.message);
// actual error will get caught by getDevicesWithRetry
});
this.getDevicesWithRetry(120000, cb);
}.bind(this));
};

View File

@@ -29,15 +29,19 @@ UiAutomator.prototype.start = function (readyCb) {
logger.info("Running bootstrap");
var args = ["shell", "uiautomator", "runtest", "AppiumBootstrap.jar", "-c",
"io.appium.android.bootstrap.Bootstrap"];
try {
this.proc = this.adb.spawn(args);
} catch (err) {
return readyCb(new Error("Could not start adb, is it around?"));
}
this.alreadyExited = false;
this.onSocketReady = readyCb;
this.proc = this.adb.spawn(args);
this.proc.on("error", function (err) {
logger.error("Unable to spawn adb: " + err.message);
if (!this.alreadyExited) {
this.alreadyExited = true;
readyCb(new Error("Unable to start Android Debug Bridge: " +
err.message));
}
}.bind(this));
this.proc.stdout.on('data', this.outputStreamHandler.bind(this));
this.proc.stderr.on('data', this.errorStreamHandler.bind(this));
this.proc.on('exit', this.exitHandler.bind(this));
@@ -206,7 +210,7 @@ UiAutomator.prototype.handleBootstrapOutput = function (output) {
UiAutomator.prototype.errorStreamHandler = function (output) {
var lines = output.toString().split("\n");
_.each(lines, function(line) {
_.each(lines, function (line) {
logger.info(("[UIAUTOMATOR STDERR] " + line).yellow);
});
};

View File

@@ -231,11 +231,20 @@ Instruments.prototype.launch = function (cb) {
return cb(err);
}
try {
this.proc = this.spawnInstruments(tmpDir);
} catch (err) {
return cb(err);
}
this.instrumentsExited = false;
this.proc = this.spawnInstruments(tmpDir);
this.proc.on("error", function (err) {
logger.info("Error with instruments proc: " + err.message);
if (err.message.indexOf("ENOENT") !== -1) {
this.proc = null; // otherwise we'll try to send sigkill
if (!this.instrumentsExited) {
this.instrumentsExited = true;
cb(new Error("Unable to spawn instruments: " + err.message));
}
}
}.bind(this));
// start waiting for instruments to launch successfully
this.socketConnectTimeout = setTimeout(
this.onSocketNeverConnect.bind(this),
@@ -245,7 +254,12 @@ Instruments.prototype.launch = function (cb) {
this.proc.stderr.setEncoding('utf8');
this.proc.stdout.pipe(through(this.outputStreamHandler.bind(this)));
this.proc.stderr.pipe(through(this.errorStreamHandler.bind(this)));
this.proc.on('exit', this.onInstrumentsExit.bind(this));
this.proc.on('exit', function (code) {
if (!this.instrumentsExited) {
this.instrumentsExited = true;
this.onInstrumentsExit(code);
}
}.bind(this));
};
Instruments.prototype.spawnInstruments = function (tmpDir) {

View File

@@ -37,11 +37,11 @@ var watchForUnresponsiveInstruments = function (cb) {
process.stderr.setEncoding('utf8');
process.stderr.pipe(through(function (data) {
logger.info('[FQInstruments] ' + cleanLogs(data.trim()));
logger.info('[FQInstruments STDERR] ' + cleanLogs(data.trim()));
}));
process.stdout.pipe(through(function (data) {
logger.info('[FQInstruments STDERR] ' + cleanLogs(data.trim()));
logger.info('[FQInstruments] ' + cleanLogs(data.trim()));
}));
cb();