From dd4cec84bfe5706a5e06f48724b0d318390e8fdd Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Tue, 17 Mar 2015 13:40:12 +0000
Subject: [PATCH] Add node.send/on to Function node
---
nodes/core/core/80-function.html | 18 ++++--
nodes/core/core/80-function.js | 75 ++++++++++++++++--------
test/nodes/core/core/80-function_spec.js | 14 +++--
3 files changed, 72 insertions(+), 35 deletions(-)
diff --git a/nodes/core/core/80-function.html b/nodes/core/core/80-function.html
index c415f9791..70c4290e8 100644
--- a/nodes/core/core/80-function.html
+++ b/nodes/core/core/80-function.html
@@ -39,15 +39,21 @@
The message is passed in as a JavaScript object called msg
.
By convention it will have a msg.payload
property containing
the body of the message.
- If your node need to log anything use the node
object:
+
Logging and Error Handling
+ To log any information, or report an error, the following functions are available:
- - Info:
node.log(msg);
- - Warning:
node.warn(msg);
- - Error:
node.error(msg);
+ node.log("Log")
+ node.warn("Warning")
+ node.error("Error")
- The function should return the messages it wants to pass on to the next nodes
- in the flow. It can return:
+ The Catch node can also be used to handle errors. To invoke a Catch node,
+ pass msg
as a second argument to node.error
:
+ node.error("Error",msg)
+ Sending messages
+ The function can either return the messages it wants to pass on to the next nodes
+ in the flow, or can call node.send(messages)
.
+ It can return/send:
- a single message object - passed to nodes connected to the first output
- an array of message objects - passed to nodes connected to the corresponding outputs
diff --git a/nodes/core/core/80-function.js b/nodes/core/core/80-function.js
index 96681bd88..c33907358 100644
--- a/nodes/core/core/80-function.js
+++ b/nodes/core/core/80-function.js
@@ -19,19 +19,57 @@ module.exports = function(RED) {
var util = require("util");
var vm = require("vm");
+
+ function sendResults(node,_msgid,msgs) {
+ if (msgs == null) {
+ return;
+ } else if (!util.isArray(msgs)) {
+ msgs = [msgs];
+ }
+ var msgCount = 0;
+ for (var m=0;m0) {
+ node.send(msgs);
+ }
+
+ }
+
function FunctionNode(n) {
RED.nodes.createNode(this,n);
var node = this;
this.name = n.name;
this.func = n.func;
- var functionText = "var results = null; results = (function(msg){\n"+this.func+"\n})(msg);";
+ var functionText = "var results = null;"+
+ "results = (function(msg){ "+
+ "var __msgid__ = msg._msgid;"+
+ "var node = {"+
+ "log:__node__.log,"+
+ "error:__node__.error,"+
+ "warn:__node__.warn,"+
+ "on:__node__.on,"+
+ "send:function(msgs){ __node__.send(__msgid__,msgs);}"+
+ "};\n"+
+ this.func+"\n"+
+ "})(msg);";
this.topic = n.topic;
var sandbox = {
console:console,
util:util,
Buffer:Buffer,
- node: {
- log : function() {
+ __node__: {
+ log: function() {
node.log.apply(node, arguments);
},
error: function(){
@@ -39,11 +77,18 @@ module.exports = function(RED) {
},
warn: function() {
node.warn.apply(node, arguments);
+ },
+ send: function(id,msgs) {
+ sendResults(node,id,msgs);
+ },
+ on: function() {
+ node.on.apply(node,arguments);
}
},
context: {
global:RED.settings.functionGlobalContext || {}
- }
+ },
+ setTimeout: setTimeout
};
var context = vm.createContext(sandbox);
try {
@@ -53,26 +98,8 @@ module.exports = function(RED) {
var start = process.hrtime();
context.msg = msg;
this.script.runInContext(context);
- var results = context.results;
- if (results == null) {
- results = [];
- } else if (results.length == null) {
- results = [results];
- }
- if (msg._topic) {
- for (var m in results) {
- if (results[m]) {
- if (util.isArray(results[m])) {
- for (var n=0; n < results[m].length; n++) {
- results[m][n]._topic = msg._topic;
- }
- } else {
- results[m]._topic = msg._topic;
- }
- }
- }
- }
- this.send(results);
+ sendResults(this,msg._msgid,context.results);
+
var duration = process.hrtime(start);
var converted = Math.floor((duration[0]* 1e9 + duration[1])/10000)/100;
this.metric("duration", msg, converted);
diff --git a/test/nodes/core/core/80-function_spec.js b/test/nodes/core/core/80-function_spec.js
index 187b37a3d..e32f2bd6e 100644
--- a/test/nodes/core/core/80-function_spec.js
+++ b/test/nodes/core/core/80-function_spec.js
@@ -105,13 +105,17 @@ describe('function node', function() {
var count = 0;
n2.on("input", function(msg) {
count++;
- should(msg).have.property('payload', count);
- should(msg).have.property('_topic', 'baz');
- if (count == 2) {
- done();
+ try {
+ should(msg).have.property('payload', count);
+ should(msg).have.property('_msgid', 1234);
+ if (count == 2) {
+ done();
+ }
+ } catch(err) {
+ done(err);
}
});
- n1.receive({payload:"foo", topic: "bar", _topic:"baz"});
+ n1.receive({payload:"foo", topic: "bar",_msgid:1234});
});
});