Skip to content

Commit

Permalink
Implements propsWithErrors
Browse files Browse the repository at this point in the history
  • Loading branch information
Dalton committed Jun 7, 2016
1 parent 45dbe99 commit b75897a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 36 deletions.
4 changes: 4 additions & 0 deletions README.md
Expand Up @@ -53,6 +53,10 @@ return Promise.resolve(customerIds)
});
```

## propsWithErrors(promises)

Like Promise.props, but returning AggregateError with each error.

# License

Check [here](LICENSE).
Expand Down
17 changes: 13 additions & 4 deletions lib/ff.js
@@ -1,10 +1,19 @@
var fns = require('./fns');

exports.install = function(target) {
exports.install = function(target, isStatic) {
Object.keys(fns).forEach(function(name) {
target[name] = function() {
return this.then(fns[name].apply(null, arguments));
};

if (isStatic) {
target[name] = function() {
var args = [].slice.call(arguments, 0)

return fns[name].apply(null, args.slice(1))(args[0]);
};
} else {
target[name] = function() {
return this.then(fns[name].apply(null, arguments));
};
}
});
};

Expand Down
86 changes: 56 additions & 30 deletions lib/fns.js
@@ -1,48 +1,74 @@
var util = require('util');
var util = require('util');
var Promise = require('./index');

exports.pif = pif;
exports.when = when;
exports.unless = unless;
exports.and = and;
exports.pif = pif;
exports.when = when;
exports.unless = unless;
exports.and = and;
exports.propsWithErrors = propsWithErrors;

function identity(a) {
return a;
return a;
}

function pif(test, consequent, alternate) {
return function(value) {
return test(value) ? consequent(value) : alternate(value);
};
return function(value) {
return test(value) ? consequent(value) : alternate(value);
};
}

function when(test, f) {
return pif(test, f, identity);
return pif(test, f, identity);
}

function unless(test, f) {
return pif(test, identity, f);
return pif(test, identity, f);
}

function and(fn) {
return function(arg) {
if (!arg || !util.isArray(arg) || arg.__ff_and_sig !== true) {
arg = [arg];

Object.defineProperty(arg, '__ff_and_sig', {
configurable: false,
writable: false,
enumerable: false,
value: true
});
}

return Promise.resolve(fn.apply(this, arg))
.then(function(result) {
arg.push(result);

return arg;
});
};
return function(arg) {
if (!arg || !util.isArray(arg) || arg.__ff_and_sig !== true) {
arg = [arg];

Object.defineProperty(arg, '__ff_and_sig', {
configurable: false,
writable: false,
enumerable: false,
value: true
});
}

return Promise.resolve(fn.apply(this, arg))
.then(function(result) {
arg.push(result);

return arg;
});
};
}

function propsWithErrors() {
return function(_promises){
var errors = new Promise.AggregateError();
var safePromises = {};

return Promise.resolve(_promises).then(function(promises){
for(var key in promises){
safePromises[key] = Promise.resolve(promises[key]).catch(pushError);
}

return Promise.props(safePromises).then(function(result){
if(errors.length > 0){
throw errors;
} else {
return result;
}
})
})

function pushError(err){
errors.push(err);
return null;
}
}
}
3 changes: 2 additions & 1 deletion lib/index.js
Expand Up @@ -2,5 +2,6 @@ var Promise = require("bluebird/js/release/promise")();

module.exports = Promise;

require('./ff').install(Promise.prototype);
require('./ff').install(Promise, true);
require('./ff').install(Promise.prototype, false);

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "bluebird-ff",
"version": "2.0.0",
"version": "2.0.1",
"description": "Functional/Control-Flow utilities for Bluebird",
"main": "lib/index.js",
"scripts": {
Expand Down
27 changes: 27 additions & 0 deletions test/propsWithErrors.js
@@ -0,0 +1,27 @@
var chai = require('chai');
var Promise = require('../lib');
var expect = chai.expect;

chai.use(require('chai-as-promised'));

describe('propsWithErrors', function() {
it('should behave like props when no errors', function() {
var promise = Promise.propsWithErrors({
first: Promise.resolve('1st'),
second: Promise.resolve('2nd')
});

return expect(promise).to.eventually.eql({first: '1st', second: '2nd'});
});

it('should throw aggregareError', function() {
var promise = Promise.propsWithErrors({
pass: Promise.resolve('pass'),
explode: Promise.reject('exploded'),
throws: Promise.reject('threw')
});

return expect(promise).to.be.rejectedWith(Promise.AggregateError);
});
});

0 comments on commit b75897a

Please sign in to comment.