Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

bubble errors up better

  • Loading branch information...
commit dce3e10e32cdfe8152e2bfa53611a1de91a6a817 1 parent ddd1c21
@bryanpaluch authored
View
1  examples/simple.js
@@ -32,6 +32,7 @@ var ruleHeat = {
ruleEngine.doRule(ruleHeat, {temp: 60, setTemp: 62, relay: 1}, function(err, then){
if(err){
+ console.log(err);
console.log("received error while applying rule logic");
}
if(then){
View
35 libs/JsonRules.js
@@ -11,9 +11,13 @@ function JsonRules( options){
//false if rule doesn't
JsonRules.prototype.doRule= function(rule, value, cb){
-var self= this;
- this.test(rule.ifs, value, function(result){
- if(result){
+ var self= this;
+ this.test(rule.ifs, value, function(err, result){
+ if(err){
+ if(cb)
+ cb(err, null);
+ }
+ else if(result){
var fn = self.getThen(rule, value);
if(cb){
cb(null, fn);
@@ -37,10 +41,17 @@ JsonRules.prototype.test = function(ifs, value, cb){
});
async.parallel(testFns, function(err, results){
if(err){
- cb(false);
+ if(err === "short-circuit")
+ cb(null, false);
+ else
+ cb(err, false);
+ }
+ else if(_.every(results,function(i){return i})){
+ cb(null, true);
+ }
+ else{
+ cb(null, false);
}
- else
- cb(true);
});
}
@@ -50,17 +61,19 @@ JsonRules.prototype._testIf = function(ifstatement, values, cb){
//test each attr if they are _object, _value or Catalog functions
//return the async capatible function for returning that value
var fns = _.map(operands, function(operand){
- if(operand._object)
+ if(_.has(operand, '_object'))
return function(cb){cb(null, values[operand._object])};
- else if(operand._value)
+ else if(_.has(operand, '_value'))
return function(cb){cb(null, operand._value)};
- else if(operand._catalog){
+ else if(_.has(operand,'_catalog')){
var fn = self.getWrappedCatalogFn(operand._catalog, values);
if(fn){
return function(cb){return fn(cb)};
}
else
return function(cb){return cb("error", false);};
+ }else{
+ return function(cb){cb(new Error("unsupported operand type"), false)};
}
});
//get values and then test
@@ -68,7 +81,7 @@ JsonRules.prototype._testIf = function(ifstatement, values, cb){
//rules that are false
async.parallel(fns, function(err, results){
if(err){
- return cb("error", false);
+ return cb(err, false);
}
var result = null;
switch(ifstatement.test){
@@ -102,7 +115,7 @@ JsonRules.prototype._testIf = function(ifstatement, values, cb){
if(result){
return cb(null, true);
}else{
- return cb("error", false);
+ return cb("short-circuit", false);
}
});
}
View
2  package.json
@@ -1,6 +1,6 @@
{
"name": "jsonrules",
- "version": "0.0.2",
+ "version": "0.0.3",
"description": "A rule engine with pure json based syntax and function catalog",
"main": "index.js",
"scripts": {
View
33 tests/2.jsonRules.js
@@ -61,7 +61,11 @@ var shortCircuitRule = {
args: ['_object.temp']}
}
};
-
+var badFormatIfs =
+ { operands: [ '_ovject.relay', '_object.relay'
+ ],
+ test: '=='
+ };
var getOtherSensorByUserId = function(userid, timeout,cb){
setTimeout(function(){
@@ -89,25 +93,34 @@ describe("JsonRules._testIf", function(){
done();
});
});
- it("tests an individual if statement, returns (\"error\",null) if false", function(done){
+ it("tests an individual if statement, returns (\"short-circuit\",false) if false with no errors", function(done){
var ruleEngine = new JsonRules();
ruleEngine._testIf(ifs[0], value2, function(err, results){
- assert.equal(err, "error");
+ assert.equal(err, "short-circuit");
+ assert.equal(results, false);
+ done();
+ });
+ });
+ it("tests an individual if statement, returns (new Error,false) if there are errors", function(done){
+ var ruleEngine = new JsonRules();
+ ruleEngine._testIf(badFormatIfs, value2, function(err, results){
+ assert.equal(typeof err, typeof (new Error("Some error")));
+ assert.equal(results, false);
done();
});
});
});
describe("JsonRules.test", function(){
- it("tests an array of if statements, and callbacks true if they pass", function(done){
+ it("tests an array of if statements, and callbacks(null, true) if they pass", function(done){
var ruleEngine = new JsonRules();
- ruleEngine.test(ifs, value1, function(result){
+ ruleEngine.test(ifs, value1, function(err, result){
assert.equal(result, true);
done();
});
});
- it("tests an array of if statements, and callbacks false if they fail", function(done){
+ it("tests an array of if statements, and callbacks (null, false) if they fail with no errors", function(done){
var ruleEngine = new JsonRules();
- ruleEngine.test(ifs, value2, function(result){
+ ruleEngine.test(ifs, value2, function(err, result){
assert.equal(result, false);
done();
});
@@ -149,12 +162,12 @@ describe("JsonRules.doRule", function(){
assert.equal(fn(), exampleThen());
done();
}else{
- throw("Should have received Then but didn't");
+ throw(new Error("Should have received Then but didn't"));
}
});
});
it("tests a rule with an catalog attribute and returns a null fn after the first false if statement fails", function(done){
- this.timeout(1200);
+ this.timeout(2000);
var exampleThen = function(word){return "example"}
var catalog = new FnCatalog();
catalog.addFn(exampleThen, 'setTemp', this);
@@ -162,7 +175,7 @@ describe("JsonRules.doRule", function(){
var ruleEngine = new JsonRules({catalog: catalog});
ruleEngine.doRule(shortCircuitRule, value1, function(err, fn){
if(fn){
- throw("Shouldn't have returned a function");
+ throw(new Error("Shouldn't have returned a function"));
}else{
done();
}
Please sign in to comment.
Something went wrong with that request. Please try again.