Better error handling around a method call

- Make sure not to double-resolve a future (using two different
  techniques!)

- Try/finally cleanup some resources
This commit is contained in:
David Glasser
2014-03-05 13:32:31 -08:00
parent ea64ed1dab
commit fdc7209dff
2 changed files with 23 additions and 10 deletions

View File

@@ -6,7 +6,7 @@ var files = require('./files.js');
var config = require('./config.js');
var httpHelpers = require('./http-helpers.js');
var archinfo = require('./archinfo.js');
var inFiber = require('./fiber-helpers.js').inFiber;
var fiberHelpers = require('./fiber-helpers.js');
var release = require('./release.js');
var querystring = require('querystring');
var url = require('url');
@@ -109,21 +109,25 @@ var sessionMethodCaller = function (methodName, options) {
});
var fut = new Future();
var conn = options.connection || openAccountsConnection();
conn.apply(methodName, args, fut.resolver());
conn.apply(methodName, args, fiberHelpers.firstTimeResolver(fut));
if (options.timeout !== undefined) {
var timer = setTimeout(inFiber(function () {
fut.throw(new Error('Method call timed out'));
var timer = setTimeout(fiberHelpers.inFiber(function () {
if (!fut.isResolved())
fut.throw(new Error('Method call timed out'));
}), options.timeout);
}
var result = fut.wait();
if (timer) {
clearTimeout(timer);
try {
var result = fut.wait();
} finally {
if (timer) {
clearTimeout(timer);
}
if (! options.connection)
conn.close();
}
if (result && result.session) {
auth.setSessionId(config.getAccountsDomain(), result.session);
}
if (! options.connection)
conn.close();
return result && result.result;
};
};
@@ -816,7 +820,7 @@ exports.pollForRegistrationCompletion = function (options) {
fut['return'](result);
});
var timer = setTimeout(inFiber(function () {
var timer = setTimeout(fiberHelpers.inFiber(function () {
if (! fut.isResolved()) {
fut['return'](null);
}

View File

@@ -37,3 +37,12 @@ exports.parallelEach = function (collection, callback, context) {
// Throw if any threw.
_.each(futures, function (f) { f.get(); });
};
exports.firstTimeResolver = function (fut) {
var resolver = fut.resolver();
return function (err, val) {
if (fut.isResolved())
return;
resolver(err, val);
};
};