Move debug encode/decode to utils for reuse

This commit is contained in:
Nick O'Leary 2018-06-25 22:31:11 +01:00
parent fa09c7c8b2
commit fe22cedc1d
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
5 changed files with 176 additions and 143 deletions

View File

@ -34,6 +34,8 @@ RED.utils = (function() {
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').text('buffer['+value.length+']');
} else if (value.hasOwnProperty('type') && value.type === 'array' && value.hasOwnProperty('data')) {
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').text('array['+value.length+']');
} else if (value.hasOwnProperty('type') && value.type === 'function') {
result = $('<span class="debug-message-object-value debug-message-type-meta"></span>').text('function');
} else {
result = $('<span class="debug-message-object-value debug-message-type-meta">object</span>');
}
@ -125,7 +127,7 @@ RED.utils = (function() {
e.stopPropagation();
RED.clipboard.copyText(msg,copyPayload,"clipboard.copyMessageValue");
})
if (strippedKey !== '') {
if (strippedKey !== undefined && strippedKey !== '') {
var isPinned = pinnedPaths[sourceId].hasOwnProperty(strippedKey);
var pinPath = $('<button class="editor-button editor-button-small debug-message-tools-pin"><i class="fa fa-map-pin"></i></button>').appendTo(tools).click(function(e) {
@ -296,9 +298,12 @@ RED.utils = (function() {
isArray = true;
isArrayObject = true;
}
if (obj === null || obj === undefined) {
$('<span class="debug-message-type-null">'+obj+'</span>').appendTo(entryObj);
} else if (typeHint === "function" || (obj.__encoded__ && obj.type === 'function')) {
e = $('<span class="debug-message-type-meta debug-message-object-header"></span>').text("function").appendTo(entryObj);
} else if (typeHint === "internal" || (obj.__encoded__ && obj.type === 'internal')) {
e = $('<span class="debug-message-type-meta debug-message-object-header"></span>').text("[internal]").appendTo(entryObj);
} else if (typeof obj === 'string') {
if (/[\t\n\r]/.test(obj)) {
element.addClass('collapsed');
@ -791,6 +796,29 @@ RED.utils = (function() {
return spinner;
}
function decodeObject(payload,format) {
if ((format === 'number') && (payload === "NaN")) {
payload = Number.NaN;
} else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
payload = JSON.parse(payload);
} else if (/error/i.test(format)) {
payload = JSON.parse(payload);
payload = (payload.name?payload.name+": ":"")+payload.message;
} else if (format === 'null') {
payload = null;
} else if (format === 'undefined') {
payload = undefined;
} else if (/^buffer/.test(format)) {
var buffer = payload;
payload = [];
for (var c = 0; c < buffer.length; c += 2) {
payload.push(parseInt(buffer.substr(c, 2), 16));
}
}
return payload;
}
return {
createObjectElement: buildMessageElement,
getMessageProperty: getMessageProperty,
@ -800,6 +828,7 @@ RED.utils = (function() {
getDefaultNodeIcon: getDefaultNodeIcon,
getNodeIcon: getNodeIcon,
getNodeLabel: getNodeLabel,
addSpinnerOverlay: addSpinnerOverlay
addSpinnerOverlay: addSpinnerOverlay,
decodeObject: decodeObject
}
})();

View File

@ -64,22 +64,22 @@
display: inline-block;
}
}
.debug-message-row {
.debug-message-tools-pin {
display: none;
}
&.debug-message-row-pinned .debug-message-tools-pin {
display: inline-block;
}
&:hover {
background: #f3f3f3;
&>.debug-message-tools {
.debug-message-tools-copy {
display: inline-block;
}
.debug-message-tools-pin {
display: inline-block;
}
}
.debug-message-row {
.debug-message-tools-pin {
display: none;
}
&.debug-message-row-pinned .debug-message-tools-pin {
display: inline-block;
}
&:hover {
background: #f3f3f3;
&>.debug-message-tools {
.debug-message-tools-copy {
display: inline-block;
}
.debug-message-tools-pin {
display: inline-block;
}
}
}

View File

@ -4,7 +4,6 @@ module.exports = function(RED) {
var util = require("util");
var events = require("events");
var path = require("path");
var safeJSONStringify = require("json-stringify-safe");
var debuglength = RED.settings.debugMaxLength || 1000;
var useColors = RED.settings.debugUseColors || false;
util.inspect.styles.boolean = "red";
@ -104,111 +103,7 @@ module.exports = function(RED) {
function sendDebug(msg) {
// don't put blank errors in sidebar (but do add to logs)
//if ((msg.msg === "") && (msg.hasOwnProperty("level")) && (msg.level === 20)) { return; }
if (msg.msg instanceof Error) {
msg.format = "error";
var errorMsg = {};
if (msg.msg.name) {
errorMsg.name = msg.msg.name;
}
if (msg.msg.hasOwnProperty('message')) {
errorMsg.message = msg.msg.message;
} else {
errorMsg.message = msg.msg.toString();
}
msg.msg = JSON.stringify(errorMsg);
} else if (msg.msg instanceof Buffer) {
msg.format = "buffer["+msg.msg.length+"]";
msg.msg = msg.msg.toString('hex');
if (msg.msg.length > debuglength) {
msg.msg = msg.msg.substring(0,debuglength);
}
} else if (msg.msg && typeof msg.msg === '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";
}
if (/error/i.test(msg.format)) {
msg.msg = JSON.stringify({
name: msg.msg.name,
message: msg.msg.message
});
} else {
var isArray = util.isArray(msg.msg);
if (isArray) {
msg.format = "array["+msg.msg.length+"]";
if (msg.msg.length > debuglength) {
// msg.msg = msg.msg.slice(0,debuglength);
msg.msg = {
__encoded__: 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 = "[internal]"
} else if (value instanceof Error) {
value = value.toString()
} else if (util.isArray(value) && value.length > debuglength) {
value = {
__encoded__: 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 (value && value.constructor) {
if (value.type === "Buffer") {
value.__encoded__ = 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]"; }
}
}
} else if (typeof msg.msg === "boolean") {
msg.format = "boolean";
msg.msg = msg.msg.toString();
} else if (typeof msg.msg === "number") {
msg.format = "number";
msg.msg = msg.msg.toString();
} else if (msg.msg === 0) {
msg.format = "number";
msg.msg = "0";
} else if (msg.msg === null || typeof msg.msg === "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 (msg.msg.length > debuglength) {
// msg.msg = msg.msg.substr(0,debuglength) +" ....";
// }
msg = RED.util.encodeObject(msg,{maxLength:debuglength});
RED.comms.publish("debug",msg);
}

View File

@ -455,24 +455,8 @@ RED.debug = (function() {
$('<span class="debug-message-name">'+name+'</span>').appendTo(metaRow);
}
if ((format === 'number') && (payload === "NaN")) {
payload = Number.NaN;
} else if (format === 'Object' || /^array/.test(format) || format === 'boolean' || format === 'number' ) {
payload = JSON.parse(payload);
} else if (/error/i.test(format)) {
payload = JSON.parse(payload);
payload = (payload.name?payload.name+": ":"")+payload.message;
} else if (format === 'null') {
payload = null;
} else if (format === 'undefined') {
payload = undefined;
} else if (/^buffer/.test(format)) {
var buffer = payload;
payload = [];
for (var c = 0; c < buffer.length; c += 2) {
payload.push(parseInt(buffer.substr(c, 2), 16));
}
}
payload = RED.utils.decodeObject(payload,format);
var el = $('<span class="debug-message-payload"></span>').appendTo(msg);
var path = o.property||'';
var debugMessage = RED.utils.createObjectElement(payload, {

View File

@ -16,6 +16,8 @@
var clone = require("clone");
var jsonata = require("jsonata");
var safeJSONStringify = require("json-stringify-safe");
var util = require("util");
function generateId() {
return (1+Math.random()*4294967295).toString(16);
@ -389,7 +391,130 @@ function normaliseNodeTypeName(name) {
return result;
}
function encodeObject(msg,opts) {
var debuglength = 1000;
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')) {
errorMsg.message = msg.msg.message;
} else {
errorMsg.message = msg.msg.toString();
}
msg.msg = JSON.stringify(errorMsg);
} else if (msg.msg instanceof Buffer) {
msg.format = "buffer["+msg.msg.length+"]";
msg.msg = msg.msg.toString('hex');
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";
}
if (/error/i.test(msg.format)) {
msg.msg = JSON.stringify({
name: msg.msg.name,
message: msg.msg.message
});
} else {
var isArray = util.isArray(msg.msg);
if (isArray) {
msg.format = "array["+msg.msg.length+"]";
if (msg.msg.length > debuglength) {
// msg.msg = msg.msg.slice(0,debuglength);
msg.msg = {
__encoded__: 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 = {
__encoded__: true,
type: "internal"
}
} else if (value instanceof Error) {
value = value.toString()
} else if (util.isArray(value) && value.length > debuglength) {
value = {
__encoded__: 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 = {
__encoded__: true,
type: "function"
}
} else if (value && value.constructor) {
if (value.type === "Buffer") {
value.__encoded__ = 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]"; }
}
}
} 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 === 0) {
msg.format = "number";
msg.msg = "0";
} 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)+"...";
}
}
return msg;
}
module.exports = {
encodeObject: encodeObject,
ensureString: ensureString,
ensureBuffer: ensureBuffer,
cloneMessage: cloneMessage,