Improve handling of incorrect return data of Function Nodes

This commit is contained in:
Jan Oberhauser 2019-12-23 14:54:27 -06:00
parent 2b343a4aa5
commit 1ed5a4589d
4 changed files with 33 additions and 3 deletions

View file

@ -324,7 +324,7 @@ export default mixins(
}, },
jsonData (): IDataObject[] { jsonData (): IDataObject[] {
const inputData = this.getNodeInputData(this.node, this.runIndex, this.outputIndex); const inputData = this.getNodeInputData(this.node, this.runIndex, this.outputIndex);
if (inputData.length === 0) { if (inputData.length === 0 || !Array.isArray(inputData)) {
return []; return [];
} }

View file

@ -226,7 +226,7 @@ export const nodeHelpers = mixins(
// Returns the data of the main input // Returns the data of the main input
getMainInputData (connectionsData: ITaskDataConnections, outputIndex: number): INodeExecutionData[] { getMainInputData (connectionsData: ITaskDataConnections, outputIndex: number): INodeExecutionData[] {
if (!connectionsData || !connectionsData.hasOwnProperty('main') || connectionsData.main === undefined || connectionsData.main.length < outputIndex) { if (!connectionsData || !connectionsData.hasOwnProperty('main') || connectionsData.main === undefined || connectionsData.main.length < outputIndex || connectionsData.main[outputIndex] === null) {
return []; return [];
} }
return connectionsData.main[outputIndex] as INodeExecutionData[]; return connectionsData.main[outputIndex] as INodeExecutionData[];

View file

@ -80,11 +80,36 @@ export class Function implements INodeType {
try { try {
// Execute the function code // Execute the function code
items = await vm.run(`module.exports = async function() {${functionCode}}()`); items = (await vm.run(`module.exports = async function() {${functionCode}}()`));
} catch (e) { } catch (e) {
return Promise.reject(e); return Promise.reject(e);
} }
// Do very basic validation of the data
if (items === undefined) {
throw new Error('No data got returned. Always return an Array of items!');
}
if (!Array.isArray(items)) {
throw new Error('Always an Array of items has to be returned!');
}
for (const item of items) {
if (item.json === undefined) {
throw new Error('All returned items have to contain property named "json"!');
}
if (item.json === undefined) {
throw new Error('All returned items have to contain a property named "json"!');
}
if (typeof item.json !== 'object') {
throw new Error('The json-property has to be an object!');
}
if (item.binary !== undefined) {
if (Array.isArray(item.binary) || typeof item.binary !== 'object') {
throw new Error('The binary-property has to be an object!');
}
}
}
return this.prepareOutputData(items); return this.prepareOutputData(items);
} }
} }

View file

@ -92,6 +92,11 @@ export class FunctionItem implements INodeType {
return Promise.reject(e); return Promise.reject(e);
} }
// Do very basic validation of the data
if (jsonData === undefined) {
throw new Error('No data got returned. Always an object has to be returned!');
}
return { return {
json: jsonData json: jsonData
}; };