mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge pull request #2366 from btsimonh/fix-encodeObjecterror
Catches bad objects being encoded, returning instead the error.
This commit is contained in:
commit
1f5ff0c6d3
@ -84,9 +84,14 @@ var consoleLogger = function(msg) {
|
|||||||
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack);
|
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+msg.msg.stack);
|
||||||
} else {
|
} else {
|
||||||
var message = msg.msg;
|
var message = msg.msg;
|
||||||
if (typeof message === 'object' && message !== null && message.toString() === '[object Object]' && message.message) {
|
try {
|
||||||
message = message.message;
|
if (typeof message === 'object' && message !== null && message.toString() === '[object Object]' && message.message) {
|
||||||
|
message = message.message;
|
||||||
|
}
|
||||||
|
} catch(e){
|
||||||
|
message = 'Exception trying to log: '+util.inspect(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message);
|
util.log("["+levelNames[msg.level]+"] "+(msg.type?"["+msg.type+":"+(msg.name||msg.id)+"] ":"")+message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
244
packages/node_modules/@node-red/util/lib/util.js
vendored
244
packages/node_modules/@node-red/util/lib/util.js
vendored
@ -652,130 +652,148 @@ function normaliseNodeTypeName(name) {
|
|||||||
* @memberof @node-red/util_util
|
* @memberof @node-red/util_util
|
||||||
*/
|
*/
|
||||||
function encodeObject(msg,opts) {
|
function encodeObject(msg,opts) {
|
||||||
var debuglength = 1000;
|
try {
|
||||||
if (opts && opts.hasOwnProperty('maxLength')) {
|
var debuglength = 1000;
|
||||||
debuglength = opts.maxLength;
|
if (opts && opts.hasOwnProperty('maxLength')) {
|
||||||
}
|
debuglength = opts.maxLength;
|
||||||
var msgType = typeof msg.msg;
|
|
||||||
if (msg.msg instanceof Error) {
|
|
||||||
msg.format = "error";
|
|
||||||
var errorMsg = {};
|
|
||||||
if (msg.msg.name) {
|
|
||||||
errorMsg.name = msg.msg.name;
|
|
||||||
}
|
}
|
||||||
if (msg.msg.hasOwnProperty('message')) {
|
var msgType = typeof msg.msg;
|
||||||
errorMsg.message = msg.msg.message;
|
if (msg.msg instanceof Error) {
|
||||||
} else {
|
msg.format = "error";
|
||||||
errorMsg.message = msg.msg.toString();
|
var errorMsg = {};
|
||||||
}
|
if (msg.msg.name) {
|
||||||
msg.msg = JSON.stringify(errorMsg);
|
errorMsg.name = msg.msg.name;
|
||||||
} else if (msg.msg instanceof Buffer) {
|
}
|
||||||
msg.format = "buffer["+msg.msg.length+"]";
|
if (msg.msg.hasOwnProperty('message')) {
|
||||||
msg.msg = msg.msg.toString('hex');
|
errorMsg.message = msg.msg.message;
|
||||||
if (msg.msg.length > debuglength) {
|
} else {
|
||||||
msg.msg = msg.msg.substring(0,debuglength);
|
errorMsg.message = msg.msg.toString();
|
||||||
}
|
}
|
||||||
} else if (msg.msg && msgType === 'object') {
|
msg.msg = JSON.stringify(errorMsg);
|
||||||
try {
|
} else if (msg.msg instanceof Buffer) {
|
||||||
msg.format = msg.msg.constructor.name || "Object";
|
msg.format = "buffer["+msg.msg.length+"]";
|
||||||
// Handle special case of msg.req/res objects from HTTP In node
|
msg.msg = msg.msg.toString('hex');
|
||||||
if (msg.format === "IncomingMessage" || msg.format === "ServerResponse") {
|
if (msg.msg.length > debuglength) {
|
||||||
|
msg.msg = msg.msg.substring(0,debuglength);
|
||||||
|
}
|
||||||
|
} else if (msg.msg && msgType === 'object') {
|
||||||
|
try {
|
||||||
|
msg.format = msg.msg.constructor.name || "Object";
|
||||||
|
// Handle special case of msg.req/res objects from HTTP In node
|
||||||
|
if (msg.format === "IncomingMessage" || msg.format === "ServerResponse") {
|
||||||
|
msg.format = "Object";
|
||||||
|
}
|
||||||
|
} catch(err) {
|
||||||
msg.format = "Object";
|
msg.format = "Object";
|
||||||
}
|
}
|
||||||
} catch(err) {
|
if (/error/i.test(msg.format)) {
|
||||||
msg.format = "Object";
|
msg.msg = JSON.stringify({
|
||||||
}
|
name: msg.msg.name,
|
||||||
if (/error/i.test(msg.format)) {
|
message: msg.msg.message
|
||||||
msg.msg = JSON.stringify({
|
});
|
||||||
name: msg.msg.name,
|
} else {
|
||||||
message: msg.msg.message
|
var isArray = util.isArray(msg.msg);
|
||||||
});
|
if (isArray) {
|
||||||
} else {
|
msg.format = "array["+msg.msg.length+"]";
|
||||||
var isArray = util.isArray(msg.msg);
|
if (msg.msg.length > debuglength) {
|
||||||
if (isArray) {
|
// msg.msg = msg.msg.slice(0,debuglength);
|
||||||
msg.format = "array["+msg.msg.length+"]";
|
msg.msg = {
|
||||||
if (msg.msg.length > debuglength) {
|
|
||||||
// msg.msg = msg.msg.slice(0,debuglength);
|
|
||||||
msg.msg = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "array",
|
|
||||||
data: msg.msg.slice(0,debuglength),
|
|
||||||
length: msg.msg.length
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isArray || (msg.format === "Object")) {
|
|
||||||
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
|
||||||
if (key === '_req' || key === '_res') {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "internal"
|
|
||||||
}
|
|
||||||
} else if (value instanceof Error) {
|
|
||||||
value = value.toString()
|
|
||||||
} else if (util.isArray(value) && value.length > debuglength) {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
__enc__: true,
|
||||||
type: "array",
|
type: "array",
|
||||||
data: value.slice(0,debuglength),
|
data: msg.msg.slice(0,debuglength),
|
||||||
length: value.length
|
length: msg.msg.length
|
||||||
}
|
|
||||||
} else if (typeof value === 'string') {
|
|
||||||
if (value.length > debuglength) {
|
|
||||||
value = value.substring(0,debuglength)+"...";
|
|
||||||
}
|
|
||||||
} else if (typeof value === 'function') {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "function"
|
|
||||||
}
|
|
||||||
} else if (typeof value === 'number') {
|
|
||||||
if (isNaN(value) || value === Infinity || value === -Infinity) {
|
|
||||||
value = {
|
|
||||||
__enc__: true,
|
|
||||||
type: "number",
|
|
||||||
data: value.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (value && value.constructor) {
|
|
||||||
if (value.type === "Buffer") {
|
|
||||||
value.__enc__ = true;
|
|
||||||
value.length = value.data.length;
|
|
||||||
if (value.length > debuglength) {
|
|
||||||
value.data = value.data.slice(0,debuglength);
|
|
||||||
}
|
|
||||||
} else if (value.constructor.name === "ServerResponse") {
|
|
||||||
value = "[internal]"
|
|
||||||
} else if (value.constructor.name === "Socket") {
|
|
||||||
value = "[internal]"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return value;
|
}
|
||||||
}," ");
|
if (isArray || (msg.format === "Object")) {
|
||||||
} else {
|
msg.msg = safeJSONStringify(msg.msg, function(key, value) {
|
||||||
try { msg.msg = msg.msg.toString(); }
|
if (key === '_req' || key === '_res') {
|
||||||
catch(e) { msg.msg = "[Type not printable]"; }
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "internal"
|
||||||
|
}
|
||||||
|
} else if (value instanceof Error) {
|
||||||
|
value = value.toString()
|
||||||
|
} else if (util.isArray(value) && value.length > debuglength) {
|
||||||
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "array",
|
||||||
|
data: value.slice(0,debuglength),
|
||||||
|
length: value.length
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'string') {
|
||||||
|
if (value.length > debuglength) {
|
||||||
|
value = value.substring(0,debuglength)+"...";
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'function') {
|
||||||
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "function"
|
||||||
|
}
|
||||||
|
} else if (typeof value === 'number') {
|
||||||
|
if (isNaN(value) || value === Infinity || value === -Infinity) {
|
||||||
|
value = {
|
||||||
|
__enc__: true,
|
||||||
|
type: "number",
|
||||||
|
data: value.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (value && value.constructor) {
|
||||||
|
if (value.type === "Buffer") {
|
||||||
|
value.__enc__ = true;
|
||||||
|
value.length = value.data.length;
|
||||||
|
if (value.length > debuglength) {
|
||||||
|
value.data = value.data.slice(0,debuglength);
|
||||||
|
}
|
||||||
|
} else if (value.constructor.name === "ServerResponse") {
|
||||||
|
value = "[internal]"
|
||||||
|
} else if (value.constructor.name === "Socket") {
|
||||||
|
value = "[internal]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}," ");
|
||||||
|
} else {
|
||||||
|
try { msg.msg = msg.msg.toString(); }
|
||||||
|
catch(e) { msg.msg = "[Type not printable]" + util.inspect(msg.msg); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (msgType === "function") {
|
||||||
|
msg.format = "function";
|
||||||
|
msg.msg = "[function]"
|
||||||
|
} else if (msgType === "boolean") {
|
||||||
|
msg.format = "boolean";
|
||||||
|
msg.msg = msg.msg.toString();
|
||||||
|
} else if (msgType === "number") {
|
||||||
|
msg.format = "number";
|
||||||
|
msg.msg = msg.msg.toString();
|
||||||
|
} else if (msg.msg === null || msgType === "undefined") {
|
||||||
|
msg.format = (msg.msg === null)?"null":"undefined";
|
||||||
|
msg.msg = "(undefined)";
|
||||||
|
} else {
|
||||||
|
msg.format = "string["+msg.msg.length+"]";
|
||||||
|
if (msg.msg.length > debuglength) {
|
||||||
|
msg.msg = msg.msg.substring(0,debuglength)+"...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (msgType === "function") {
|
return msg;
|
||||||
msg.format = "function";
|
} catch(e) {
|
||||||
msg.msg = "[function]"
|
msg.format = "error";
|
||||||
} else if (msgType === "boolean") {
|
var errorMsg = {};
|
||||||
msg.format = "boolean";
|
if (e.name) {
|
||||||
msg.msg = msg.msg.toString();
|
errorMsg.name = e.name;
|
||||||
} else if (msgType === "number") {
|
|
||||||
msg.format = "number";
|
|
||||||
msg.msg = msg.msg.toString();
|
|
||||||
} else if (msg.msg === null || msgType === "undefined") {
|
|
||||||
msg.format = (msg.msg === null)?"null":"undefined";
|
|
||||||
msg.msg = "(undefined)";
|
|
||||||
} else {
|
|
||||||
msg.format = "string["+msg.msg.length+"]";
|
|
||||||
if (msg.msg.length > debuglength) {
|
|
||||||
msg.msg = msg.msg.substring(0,debuglength)+"...";
|
|
||||||
}
|
}
|
||||||
|
if (e.hasOwnProperty('message')) {
|
||||||
|
errorMsg.message = 'encodeObject Error: ['+e.message + '] Value: '+util.inspect(msg.msg);
|
||||||
|
} else {
|
||||||
|
errorMsg.message = 'encodeObject Error: ['+e.toString() + '] Value: '+util.inspect(msg.msg);
|
||||||
|
}
|
||||||
|
if (errorMsg.message.length > debuglength) {
|
||||||
|
errorMsg.message = errorMsg.message.substring(0,debuglength);
|
||||||
|
}
|
||||||
|
msg.msg = JSON.stringify(errorMsg);
|
||||||
|
return msg;
|
||||||
}
|
}
|
||||||
return msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
@ -224,5 +224,29 @@ describe("@node-red/util/log", function() {
|
|||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
it('it can log without exception', function() {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
msg.msg.toString = function(){
|
||||||
|
throw new Error('Exception in toString - should have been caught');
|
||||||
|
}
|
||||||
|
msg.msg.constructor = { name: "strangeobj" };
|
||||||
|
var ret = log.info(msg.msg);
|
||||||
|
});
|
||||||
|
it('it can log an object but use .message', function() {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
message: "my special message",
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var ret = log.info(msg.msg);
|
||||||
|
sinon.assert.calledWithMatch(util.log,"my special message");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -772,6 +772,117 @@ describe("@node-red/util/util", function() {
|
|||||||
var resultJson = JSON.parse(result.msg);
|
var resultJson = JSON.parse(result.msg);
|
||||||
resultJson.socket.should.eql('[internal]');
|
resultJson.socket.should.eql('[internal]');
|
||||||
});
|
});
|
||||||
|
it('object which fails to serialise', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
obj:{
|
||||||
|
cantserialise:{
|
||||||
|
message:'this will not be displayed',
|
||||||
|
toJSON: function(val) {
|
||||||
|
throw 'this exception should have been caught';
|
||||||
|
return 'should not display because we threw first';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
canserialise:{
|
||||||
|
message:'this should be displayed',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
result.format.should.eql("error");
|
||||||
|
var success = (result.msg.indexOf('cantserialise') > 0);
|
||||||
|
success &= (result.msg.indexOf('this exception should have been caught') > 0);
|
||||||
|
success &= (result.msg.indexOf('canserialise') > 0);
|
||||||
|
success.should.eql(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('object which fails to serialise - different error type', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
obj:{
|
||||||
|
cantserialise:{
|
||||||
|
message:'this will not be displayed',
|
||||||
|
toJSON: function(val) {
|
||||||
|
throw new Error('this exception should have been caught');
|
||||||
|
return 'should not display because we threw first';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
canserialise:{
|
||||||
|
message:'this should be displayed',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
result.format.should.eql("error");
|
||||||
|
var success = (result.msg.indexOf('cantserialise') > 0);
|
||||||
|
success &= (result.msg.indexOf('this exception should have been caught') > 0);
|
||||||
|
success &= (result.msg.indexOf('canserialise') > 0);
|
||||||
|
success.should.eql(1);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('very large object which fails to serialise should be truncated', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
obj:{
|
||||||
|
big:"",
|
||||||
|
cantserialise:{
|
||||||
|
message:'this will not be displayed',
|
||||||
|
toJSON: function(val) {
|
||||||
|
throw new Error('this exception should have been caught');
|
||||||
|
return 'should not display because we threw first';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
canserialise:{
|
||||||
|
message:'this should be displayed',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < 1000; i++) {
|
||||||
|
msg.msg.obj.big += 'some more string ';
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
result.format.should.eql("error");
|
||||||
|
var resultJson = JSON.parse(result.msg);
|
||||||
|
var success = (resultJson.message.length <= 1000);
|
||||||
|
success.should.eql(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('test bad toString', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
msg.msg.toString = function(){
|
||||||
|
throw new Error('Exception in toString - should have been caught');
|
||||||
|
}
|
||||||
|
msg.msg.constructor = { name: "strangeobj" };
|
||||||
|
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
var success = (result.msg.indexOf('[Type not printable]') >= 0);
|
||||||
|
success.should.eql(true);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
it('test bad object constructor', function(done) {
|
||||||
|
var msg = {
|
||||||
|
msg: {
|
||||||
|
mystrangeobj:"hello",
|
||||||
|
constructor: {
|
||||||
|
get name(){
|
||||||
|
throw new Error('Exception in constructor name');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var result = util.encodeObject(msg);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user