diff --git a/packages/node_modules/@node-red/nodes/core/function/10-function.html b/packages/node_modules/@node-red/nodes/core/function/10-function.html index 4a07cdbfb..446ef918d 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/core/function/10-function.html @@ -366,7 +366,7 @@ name: {value:"_DEFAULT_"}, func: {value:"\nreturn msg;"}, outputs: {value:1}, - timeout:{value:0}, + timeout:{value:RED.settings.functionTimeout || 0}, noerr: {value:0,required:true, validate: function(v, opt) { if (!v) { diff --git a/packages/node_modules/@node-red/nodes/core/function/10-function.js b/packages/node_modules/@node-red/nodes/core/function/10-function.js index 662b7fa47..7f2250008 100644 --- a/packages/node_modules/@node-red/nodes/core/function/10-function.js +++ b/packages/node_modules/@node-red/nodes/core/function/10-function.js @@ -521,7 +521,8 @@ module.exports = function(RED) { RED.nodes.registerType("function",FunctionNode, { dynamicModuleList: "libs", settings: { - functionExternalModules: { value: true, exportable: true } + functionExternalModules: { value: true, exportable: true }, + functionTimeout: { value:0, exportable: true } } }); RED.library.register("functions"); diff --git a/packages/node_modules/node-red/settings.js b/packages/node_modules/node-red/settings.js index 218baa92d..698da25d8 100644 --- a/packages/node_modules/node-red/settings.js +++ b/packages/node_modules/node-red/settings.js @@ -444,6 +444,7 @@ module.exports = { * - fileWorkingDirectory * - functionGlobalContext * - functionExternalModules + * - functionTimeout * - nodeMessageBufferMaxLength * - ui (for use with Node-RED Dashboard) * - debugUseColors @@ -468,6 +469,9 @@ module.exports = { /** Allow the Function node to load additional npm modules directly */ functionExternalModules: true, + /** Default timeout, in seconds, for the Function node. 0 means no timeout is applied */ + functionTimeout: 0, + /** The following property can be used to set predefined values in Global Context. * This allows extra node modules to be made available with in Function node. * For example, the following: diff --git a/test/nodes/core/function/10-function_spec.js b/test/nodes/core/function/10-function_spec.js index 99557f0b3..acb693208 100644 --- a/test/nodes/core/function/10-function_spec.js +++ b/test/nodes/core/function/10-function_spec.js @@ -1449,6 +1449,34 @@ describe('function node', function() { }); }); + it('check if default function timeout settings are recognized', function (done) { + RED.settings.functionTimeout = 0.01; + var flow = [{id: "n1",type: "function",timeout: RED.settings.functionTimeout,wires: [["n2"]],func: "while(1==1){};\nreturn msg;"}]; + helper.load(functionNode, flow, function () { + var n1 = helper.getNode("n1"); + n1.receive({ payload: "foo", topic: "bar" }); + setTimeout(function () { + try { + helper.log().called.should.be.true(); + var logEvents = helper.log().args.filter(function (evt) { + return evt[0].type == "function"; + }); + logEvents.should.have.length(1); + var msg = logEvents[0][0]; + msg.should.have.property('level', helper.log().ERROR); + msg.should.have.property('id', 'n1'); + msg.should.have.property('type', 'function'); + should.equal(RED.settings.functionTimeout, 0.01); + should.equal(msg.msg.message, 'Script execution timed out after 10ms'); + delete RED.settings.functionTimeout; + done(); + } catch (err) { + done(err); + } + }, 500); + }); + }); + describe("finalize function", function() { it('should execute', function(done) {