Use native promise implementation if one is available, otherwise
es6-promise polyfill.
Change-Id: I41919aab18e68370d250a77cfba7f53a8f61f8be
diff --git a/package.json b/package.json
index ad5da87..a9421c3 100644
--- a/package.json
+++ b/package.json
@@ -4,7 +4,6 @@
"version": "0.1.0",
"main": "./src/vanadium",
"dependencies": {
- "bluebird": "^2.3.2",
"is-browser": "^2.0.1",
"ws": "~0.4.31",
"xtend": "^4.0.0",
@@ -15,7 +14,8 @@
"inherits": "~2.0.1",
"format": "~0.2.1",
"randombytes": "~2.0.1",
- "domready": "~1.0.7"
+ "domready": "~1.0.7",
+ "es6-promise": "~2.1.1"
},
"devDependencies": {
"node-static": "^0.7.4",
diff --git a/src/lib/deferred.js b/src/lib/deferred.js
index a11171d..68ead13 100644
--- a/src/lib/deferred.js
+++ b/src/lib/deferred.js
@@ -27,17 +27,20 @@
function addCallback(promise, cb) {
if (cb) {
- // Note, this must be a .done() and not a .then(). Errors thrown inside of
- // a .then() callback are wrapped in a try/catch, whereas errors thrown
- // inside of a .done() callback will be thrown as an error.
- promise.done(
+ promise.then(
function success(value) {
cb(null, value);
},
function error(err) {
cb(err);
}
- );
+ ).catch(function catchError(err) {
+ // Re-throw the error in a process.nextTick so that it won't be caught by
+ // the promise implementation.
+ process.nextTick(function() {
+ throw err;
+ });
+ });
}
}
diff --git a/src/lib/promise.js b/src/lib/promise.js
index fce522d..ccdecd4 100644
--- a/src/lib/promise.js
+++ b/src/lib/promise.js
@@ -5,23 +5,32 @@
/**
* @fileoverview Vanadium.js promise implementation.
*
- * Currently this is just bluebird promises.
+ * This uses the native Promise implementation in browsers, and the es6-promise
+ * polyfill in non-browsers.
*
- * We'd like our promise implementation to follow the es6/A+ promise spec, but
- * the "es6-promises" module eats errors, so we are using bluebird.
+ * WARNING: es6 promises are notorius for eating errors. Make sure to add
+ * 'catch()' to the end of promise chains so that errors can be caught and
+ * handled.
*
* See for reference:
* http://blog.soareschen.com/the-problem-with-es6-promises
* https://github.com/soareschen/es6-promise-debugging
* https://github.com/petkaantonov/bluebird#error-handling
*
- * TODO(nlacasse): Wrap bluebird promises to only expose es6/A+ promise API.
- * Otherwise users might rely on non-A+ parts of the bluebird API, preventing us
- * from switching in the future.
* @private
*/
-var Promise = require('bluebird');
-Promise.longStackTraces();
+var isBrowser = require('is-browser');
-module.exports = Promise;
+if (isBrowser) {
+ // Use native Promise implementation in browsers.
+ if (typeof Promise === 'undefined') {
+ throw new Error('No native promise implementation found.');
+ }
+ module.exports = Promise;
+} else {
+ // Use es6-promise polyfill in non-browsers.
+ // The require string is split so that browserify does not bundle es6-promise
+ // library.
+ module.exports = require('es6' + '-promise').Promise;
+}
diff --git a/test/integration/test-cancellation.js b/test/integration/test-cancellation.js
index 8c36817..a4f40f2 100644
--- a/test/integration/test-cancellation.js
+++ b/test/integration/test-cancellation.js
@@ -43,10 +43,11 @@
ctx.cancel();
return collector.waitForStatus(dctx, id, 'cancelled');
}).then(function(timeout) {
+ dctx.finish();
+ end(assert);
}).catch(function(err) {
- assert.error(err);
- }).finally(function() {
dctx.cancel();
+ assert.error(err);
end(assert);
});
}
diff --git a/test/integration/test-service-cache.js b/test/integration/test-service-cache.js
index 9dafca6..0ade094 100644
--- a/test/integration/test-service-cache.js
+++ b/test/integration/test-service-cache.js
@@ -7,7 +7,7 @@
var NoExistError = vanadium.verror.NoExistError;
var config = require('./default-config');
var service = require('./get-service');
-var Promise = require('bluebird');
+var Promise = require('../../src/lib/promise');
test('Test set() of Go sample cache service - ' +
'cache.set(key, value, callback)', function(assert) {