Function node - handle things thrown that aren't proper Error types

and add tests
to close #2269
This commit is contained in:
Dave Conway-Jones 2019-08-19 10:42:14 +01:00
parent e72faef839
commit bf14af6a1f
No known key found for this signature in database
GPG Key ID: 9E7F9C73F5168CD4
2 changed files with 96 additions and 22 deletions

View File

@ -237,35 +237,43 @@ module.exports = function(RED) {
this.status({fill:"yellow",shape:"dot",text:""+converted}); this.status({fill:"yellow",shape:"dot",text:""+converted});
} }
} catch(err) { } catch(err) {
//remove unwanted part if ((typeof err === "object") && err.hasOwnProperty("stack")) {
var index = err.stack.search(/\n\s*at ContextifyScript.Script.runInContext/); //remove unwanted part
err.stack = err.stack.slice(0, index).split('\n').slice(0,-1).join('\n'); var index = err.stack.search(/\n\s*at ContextifyScript.Script.runInContext/);
var stack = err.stack.split(/\r?\n/); err.stack = err.stack.slice(0, index).split('\n').slice(0,-1).join('\n');
var stack = err.stack.split(/\r?\n/);
//store the error in msg to be used in flows //store the error in msg to be used in flows
msg.error = err; msg.error = err;
var line = 0; var line = 0;
var errorMessage; var errorMessage;
if (stack.length > 0) { if (stack.length > 0) {
while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) { while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) {
line++; line++;
} }
if (line < stack.length) { if (line < stack.length) {
errorMessage = stack[line]; errorMessage = stack[line];
var m = /:(\d+):(\d+)$/.exec(stack[line+1]); var m = /:(\d+):(\d+)$/.exec(stack[line+1]);
if (m) { if (m) {
var lineno = Number(m[1])-1; var lineno = Number(m[1])-1;
var cha = m[2]; var cha = m[2];
errorMessage += " (line "+lineno+", col "+cha+")"; errorMessage += " (line "+lineno+", col "+cha+")";
}
} }
} }
if (!errorMessage) {
errorMessage = err.toString();
}
this.error(errorMessage, msg);
} }
if (!errorMessage) { else if (typeof err === "string") {
errorMessage = err.toString(); this.error(err, msg);
}
else {
this.error(JSON.stringify(err), msg);
} }
this.error(errorMessage, msg);
} }
}); });
this.on("close", function() { this.on("close", function() {

View File

@ -1390,6 +1390,72 @@ describe('function node', function() {
} }
}); });
}); });
it('should catch thrown string', function (done) {
var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "throw \"small mistake\";"}];
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
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');
msg.should.have.property('msg', 'small mistake');
done();
} catch (err) {
done(err);
}
});
});
it('should catch thrown number', function (done) {
var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "throw 99;"}];
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
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');
msg.should.have.property('msg', '99');
done();
} catch (err) {
done(err);
}
});
});
it('should catch thrown object (bad practise)', function (done) {
var flow = [{id: "n1", type: "function", wires: [["n2"]], func: "throw {a:1};"}];
helper.load(functionNode, flow, function () {
var n1 = helper.getNode("n1");
n1.receive({payload: "foo", topic: "bar"});
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');
msg.should.have.property('msg', '{"a":1}');
done();
} catch (err) {
done(err);
}
});
});
}); });
}); });