diff --git a/red/nodes/Flow.js b/red/nodes/Flow.js index 5f0ad559c..c5df20f68 100644 --- a/red/nodes/Flow.js +++ b/red/nodes/Flow.js @@ -208,18 +208,19 @@ function diffNodeConfigs(oldNode,newNode) { function createCatchNodeMap(nodes) { var catchNodes = {}; var subflowInstances = {}; + var id; /* - a catchNode with same z as error node - if error occurs on a subflow without catchNode, look at z of subflow instance */ - for (var id in nodes) { + for (id in nodes) { if (nodes.hasOwnProperty(id)) { if (nodes[id].type === "catch") { catchNodes[nodes[id].z] = nodes[id]; } } } - for (var id in nodes) { + for (id in nodes) { if (nodes.hasOwnProperty(id)) { var m = /^subflow:(.+)$/.exec(nodes[id].type); if (m) { @@ -227,7 +228,7 @@ function createCatchNodeMap(nodes) { } } } - for (var id in subflowInstances) { + for (id in subflowInstances) { if (subflowInstances.hasOwnProperty(id)) { var z = id; while(subflowInstances[z]) { @@ -744,8 +745,8 @@ Flow.prototype.handleError = function(node,logMessage,msg) { errorMessage.error = { message: logMessage.toString(), source: { - id: this.id, - type: this.type + id: node.id, + type: node.type } }; if (this.catchNodeMap[node.z]) { diff --git a/test/red/nodes/Flow_spec.js b/test/red/nodes/Flow_spec.js index 37da6e712..7901ce423 100644 --- a/test/red/nodes/Flow_spec.js +++ b/test/red/nodes/Flow_spec.js @@ -574,9 +574,6 @@ describe('Flow', function() { } util.inherits(TestNode,Node); - - - before(function() { getNode = sinon.stub(flows,"get",function(id) { return currentNodes[id]; @@ -809,9 +806,129 @@ describe('Flow', function() { done(); }); }); + }); + describe('#handleError',function() { + var getType; + var getNode; + var credentialsClean; + var currentNodes = {}; + var TestNode = function(n) { + Node.call(this,n); + var node = this; + this.handled = []; + currentNodes[node.id] = node; + this.on('input',function(msg) { + node.handled.push(msg); + node.send(msg); + }); + } + util.inherits(TestNode,Node); + before(function() { + getNode = sinon.stub(flows,"get",function(id) { + return currentNodes[id]; + }); + getType = sinon.stub(typeRegistry,"get",function(type) { + return TestNode; + }); + credentialsClean = sinon.stub(credentials,"clean",function(config){}); + + }); + after(function() { + getType.restore(); + credentialsClean.restore(); + getNode.restore(); + }); + + beforeEach(function() { + currentNodes = {}; + }); + + it("reports error to catch nodes on same z",function(done) { + var config = [ + {id:"1",type:"test",z:"tab1",name:"a",wires:["2"]}, + {id:"2",type:"catch",z:"tab1",wires:[[]]}, + {id:"3",type:"catch",z:"tab2",wires:[[]]} + ]; + var flow = new Flow(config); + flow.start(); + var msg = {a:1}; + flow.handleError(getNode(1),"test error",msg); + var n2 = getNode(2); + n2.handled.should.have.lengthOf(1); + n2.handled[0].should.have.property("a",1); + n2.handled[0].should.have.property("error"); + n2.handled[0].error.should.have.property("message","test error"); + n2.handled[0].error.should.have.property("source"); + n2.handled[0].error.source.should.have.property("id","1"); + n2.handled[0].error.source.should.have.property("type","test"); + getNode(3).handled.should.have.lengthOf(0); + done(); + }); + + it("reports error with undefined message object",function(done) { + var config = [ + {id:"1",type:"test",z:"tab1",name:"a",wires:["2"]}, + {id:"2",type:"catch",z:"tab1",wires:[[]]}, + {id:"3",type:"catch",z:"tab2",wires:[[]]} + ]; + var flow = new Flow(config); + flow.start(); + flow.handleError(getNode(1),"test error"); + var n2 = getNode(2); + n2.handled.should.have.lengthOf(1); + n2.handled[0].should.have.property("error"); + n2.handled[0].error.should.have.property("message","test error"); + n2.handled[0].error.should.have.property("source"); + n2.handled[0].error.source.should.have.property("id","1"); + n2.handled[0].error.source.should.have.property("type","test"); + getNode(3).handled.should.have.lengthOf(0); + done(); + }); + + it("reports error with Error object",function(done) { + var config = [ + {id:"1",type:"test",z:"tab1",name:"a",wires:["2"]}, + {id:"2",type:"catch",z:"tab1",wires:[[]]}, + {id:"3",type:"catch",z:"tab2",wires:[[]]} + ]; + var flow = new Flow(config); + flow.start(); + var msg = {a:1,error:"existing"}; + flow.handleError(getNode(1),"test error",msg); + var n2 = getNode(2); + n2.handled.should.have.lengthOf(1); + n2.handled[0].should.have.property("error"); + n2.handled[0].should.have.property("_error","existing"); + n2.handled[0].error.should.have.property("message","test error"); + n2.handled[0].error.should.have.property("source"); + n2.handled[0].error.source.should.have.property("id","1"); + n2.handled[0].error.source.should.have.property("type","test"); + getNode(3).handled.should.have.lengthOf(0); + done(); + }); + + it("reports error with Error object",function(done) { + var config = [ + {id:"1",type:"test",z:"tab1",name:"a",wires:["2"]}, + {id:"2",type:"catch",z:"tab1",wires:[[]]}, + {id:"3",type:"catch",z:"tab2",wires:[[]]} + ]; + var flow = new Flow(config); + flow.start(); + flow.handleError(getNode(1),new Error("test error")); + var n2 = getNode(2); + n2.handled.should.have.lengthOf(1); + n2.handled[0].should.have.property("error"); + n2.handled[0].error.should.have.property("message","Error: test error"); + n2.handled[0].error.should.have.property("source"); + n2.handled[0].error.source.should.have.property("id","1"); + n2.handled[0].error.source.should.have.property("type","test"); + getNode(3).handled.should.have.lengthOf(0); + done(); + }); }); }); \ No newline at end of file diff --git a/test/red/nodes/Node_spec.js b/test/red/nodes/Node_spec.js index 526fe92e7..4d2fcd8d8 100644 --- a/test/red/nodes/Node_spec.js +++ b/test/red/nodes/Node_spec.js @@ -385,10 +385,22 @@ describe('Node', function() { sinon.stub(Log, 'log', function(msg) { loginfo = msg; }); - n.error("an error message"); + sinon.stub(flows,"handleError", function(node,message,msg) { + }); + + var message = {a:1}; + + n.error("an error message",message); should.deepEqual({level:Log.ERROR, id:n.id, type:n.type, msg:"an error message"}, loginfo); + + flows.handleError.called.should.be.true; + flows.handleError.args[0][0].should.eql(n); + flows.handleError.args[0][1].should.eql("an error message"); + flows.handleError.args[0][2].should.eql(message); + Log.log.restore(); + flows.handleError.restore(); done(); }); });