1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Show error details when trying to import invalid json

This commit is contained in:
Nick O'Leary 2018-10-23 23:06:43 +01:00
parent f488869635
commit 09abec15b1
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
4 changed files with 107 additions and 5 deletions

View File

@ -170,7 +170,12 @@
},
"import": {
"import": "Import to",
"newFlow": "new flow"
"newFlow": "new flow",
"errors": {
"invalidFlowNotObject": "Input not a valid flow - item __index__ not a node object",
"invalidFlowMissingId": "Input not a valid flow - item __index__ missing 'id' property",
"invalidFlowMissingType": "Input not a valid flow - item __index__ missing 'type' property"
}
},
"copyMessagePath": "Path copied",
"copyMessageValue": "Value copied",

View File

@ -22,6 +22,8 @@ RED.clipboard = (function() {
var exportNodesDialog;
var importNodesDialog;
var disabled = false;
var popover;
var currentPopoverError;
function setupDialogs() {
dialog = $('<div id="clipboard-dialog" class="hide node-red-dialog"><form class="dialog-form form-horizontal"></form></div>')
@ -73,6 +75,8 @@ RED.clipboard = (function() {
$(this).parent().find(".ui-dialog-titlebar-close").hide();
},
close: function(e) {
popover.close(true);
currentPopoverError = null;
}
});
@ -113,16 +117,86 @@ RED.clipboard = (function() {
function validateImport() {
var importInput = $("#clipboard-import");
var v = importInput.val();
v = v.substring(v.indexOf('['),v.lastIndexOf(']')+1);
var v = importInput.val().trim();
if (v === "") {
popover.close(true);
currentPopoverError = null;
importInput.removeClass("input-error");
$("#clipboard-dialog-ok").button("disable");
return;
}
try {
JSON.parse(v);
if (!/^\[[\s\S]*\]$/m.test(v)) {
throw new Error(RED._("clipboard.import.errors.notArray"));
}
var res = JSON.parse(v);
for (var i=0;i<res.length;i++) {
if (typeof res[i] !== "object") {
throw new Error(RED._("clipboard.import.errors.itemNotObject",{index:i}));
}
if (!res[i].hasOwnProperty('id')) {
throw new Error(RED._("clipboard.import.errors.missingId",{index:i}));
}
if (!res[i].hasOwnProperty('type')) {
throw new Error(RED._("clipboard.import.errors.missingType",{index:i}));
}
}
currentPopoverError = null;
popover.close(true);
importInput.removeClass("input-error");
importInput.val(v);
$("#clipboard-dialog-ok").button("enable");
} catch(err) {
if (v !== "") {
importInput.addClass("input-error");
var errString = err.toString();
if (errString !== currentPopoverError) {
// Display the error as-is.
// Error messages are only in English. Each browser has its
// own set of messages with very little consistency.
// To provide translated messages this code will either need to:
// - reduce everything down to 'unexpected token at position x'
// which is the least useful, but most consistent message
// - use a custom/library parser that gives consistent messages
// which can be translated.
var message = $('<div class="clipboard-import-error"></div>').text(errString);
var errorPos;
// Chrome error messages
var m = /at position (\d+)/i.exec(errString);
if (m) {
errorPos = parseInt(m[1]);
} else {
// Firefox error messages
m = /at line (\d+) column (\d+)/i.exec(errString);
if (m) {
var line = parseInt(m[1])-1;
var col = parseInt(m[2])-1;
var lines = v.split("\n");
errorPos = 0;
for (var i=0;i<line;i++) {
errorPos += lines[i].length+1;
}
errorPos += col;
} else {
// Safari doesn't provide any position information
// IE: tbd
}
}
if (errorPos !== undefined) {
v = v.replace(/\n/g,"↵");
var index = parseInt(m[1]);
var parseError = $('<div>').appendTo(message);
var code = $('<pre>').appendTo(parseError);
$('<span>').text(v.substring(errorPos-12,errorPos)).appendTo(code)
$('<span class="error">').text(v.charAt(errorPos)).appendTo(code);
$('<span>').text(v.substring(errorPos+1,errorPos+12)).appendTo(code);
}
popover.close(true).setContent(message).open();
currentPopoverError = errString;
}
} else {
currentPopoverError = null;
}
$("#clipboard-dialog-ok").button("disable");
}
@ -154,6 +228,12 @@ RED.clipboard = (function() {
});
dialog.dialog("option","title",RED._("clipboard.importNodes")).dialog("open");
popover = RED.popover.create({
target: $("#clipboard-import"),
trigger: "manual",
direction: "bottom",
content: ""
});
}
function exportNodes() {

View File

@ -130,7 +130,7 @@ RED.popover = (function() {
if (!active) {
if (div) {
if (instant) {
$(this).remove();
div.remove();
} else {
div.fadeOut("fast",function() {
$(this).remove();

View File

@ -31,3 +31,20 @@
#node-select-library li.list-hover {
background: #ffffd0;
}
.clipboard-import-error {
pre {
margin: 10px 0;
border: none;
color: #666;
span {
padding: 5px 0;
}
span.error {
padding: 5px;
background: #e25151;
color: white;
margin: 0 1px;
}
}
}