Display node-error only on executing nodes (#2274)

*  Dot not display errors on disconnected nodes

*  Fix some more inconsistencies
This commit is contained in:
Jan 2021-10-06 12:02:31 -05:00 committed by GitHub
parent 9dbf6e5f6d
commit f7148bdd77
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 10 deletions

View file

@ -582,7 +582,14 @@ export class WorkflowExecute {
const startedAt = new Date();
const workflowIssues = workflow.checkReadyForExecution();
const startNode = this.runExecutionData.executionData!.nodeExecutionStack[0].node.name;
let destinationNode: string | undefined;
if (this.runExecutionData.startData && this.runExecutionData.startData.destinationNode) {
destinationNode = this.runExecutionData.startData.destinationNode;
}
const workflowIssues = workflow.checkReadyForExecution({ startNode, destinationNode });
if (workflowIssues !== null) {
throw new Error(
'The workflow has issues and can for that reason not be executed. Please fix them first.',

View file

@ -1,6 +1,9 @@
import {
ERROR_TRIGGER_NODE_NAME,
PLACEHOLDER_FILLED_AT_EXECUTION_TIME,
PLACEHOLDER_EMPTY_WORKFLOW_ID,
START_NODE_TYPE,
WEBHOOK_NODE_NAME,
} from '@/constants';
import {
@ -144,13 +147,39 @@ export const workflowHelpers = mixins(
},
// Checks if everything in the workflow is complete and ready to be executed
checkReadyForExecution (workflow: Workflow) {
checkReadyForExecution (workflow: Workflow, lastNodeName?: string) {
let node: INode;
let nodeType: INodeType | undefined;
let nodeIssues: INodeIssues | null = null;
const workflowIssues: IWorfklowIssues = {};
for (const nodeName of Object.keys(workflow.nodes)) {
let checkNodes = Object.keys(workflow.nodes);
if (lastNodeName) {
checkNodes = workflow.getParentNodes(lastNodeName);
checkNodes.push(lastNodeName);
} else {
// As webhook nodes always take presidence check first
// if there are any
let checkWebhook: string[] = [];
for (const nodeName of Object.keys(workflow.nodes)) {
if (workflow.nodes[nodeName].disabled !== true && workflow.nodes[nodeName].type === WEBHOOK_NODE_NAME) {
checkWebhook = [nodeName, ...checkWebhook, ...workflow.getChildNodes(nodeName)];
}
}
if (checkWebhook.length) {
checkNodes = checkWebhook;
} else {
// If no webhook nodes got found try to find another trigger node
const startNode = workflow.getStartNode();
if (startNode !== undefined) {
checkNodes = workflow.getChildNodes(startNode.name);
checkNodes.push(startNode.name);
}
}
}
for (const nodeName of checkNodes) {
nodeIssues = null;
node = workflow.nodes[nodeName];
@ -214,6 +243,10 @@ export const workflowHelpers = mixins(
return {
description: nodeTypeDescription,
// As we do not have the trigger/poll functions available in the frontend
// we use the information available to figure out what are trigger nodes
// @ts-ignore
trigger: ![ERROR_TRIGGER_NODE_NAME, START_NODE_TYPE].includes(nodeType) && nodeTypeDescription.inputs.length === 0 && !nodeTypeDescription.webhooks || undefined,
};
},
};

View file

@ -55,7 +55,7 @@ export const workflowRun = mixins(
return response;
},
async runWorkflow (nodeName: string, source?: string): Promise<IExecutionPushResponse | undefined> {
async runWorkflow (nodeName?: string, source?: string): Promise<IExecutionPushResponse | undefined> {
if (this.$store.getters.isActionActive('workflowRunning') === true) {
return;
}
@ -70,7 +70,7 @@ export const workflowRun = mixins(
const issuesExist = this.$store.getters.nodesIssuesExist;
if (issuesExist === true) {
// If issues exist get all of the issues of all nodes
const workflowIssues = this.checkReadyForExecution(workflow);
const workflowIssues = this.checkReadyForExecution(workflow, nodeName);
if (workflowIssues !== null) {
const errorMessages = [];
let nodeIssues: string[];
@ -94,7 +94,10 @@ export const workflowRun = mixins(
}
// Get the direct parents of the node
const directParentNodes = workflow.getParentNodes(nodeName, 'main', 1);
let directParentNodes: string[] = [];
if (nodeName !== undefined) {
directParentNodes = workflow.getParentNodes(nodeName, 'main', 1);
}
const runData = this.$store.getters.getWorkflowRunData;
@ -133,7 +136,7 @@ export const workflowRun = mixins(
}
}
if (startNodes.length === 0) {
if (startNodes.length === 0 && nodeName !== undefined) {
startNodes.push(nodeName);
}

View file

@ -54,6 +54,7 @@ export const ALL_NODE_FILTER = 'All';
export const UNCATEGORIZED_CATEGORY = 'Miscellaneous';
export const UNCATEGORIZED_SUBCATEGORY = 'Helpers';
export const HIDDEN_NODES = ['n8n-nodes-base.start'];
export const ERROR_TRIGGER_NODE_NAME = 'n8n-nodes-base.errorTrigger';
export const WEBHOOK_NODE_NAME = 'n8n-nodes-base.webhook';
export const HTTP_REQUEST_NODE_NAME = 'n8n-nodes-base.httpRequest';
export const REQUEST_NODE_FORM_URL = 'https://n8n-community.typeform.com/to/K1fBVTZ3';

View file

@ -231,13 +231,29 @@ export class Workflow {
* @returns {(IWorfklowIssues | null)}
* @memberof Workflow
*/
checkReadyForExecution(): IWorfklowIssues | null {
checkReadyForExecution(inputData: {
startNode?: string;
destinationNode?: string;
}): IWorfklowIssues | null {
let node: INode;
let nodeType: INodeType | undefined;
let nodeIssues: INodeIssues | null = null;
const workflowIssues: IWorfklowIssues = {};
for (const nodeName of Object.keys(this.nodes)) {
let checkNodes: string[] = [];
if (inputData.destinationNode) {
// If a destination node is given we have to check all the nodes
// leading up to it
checkNodes = this.getParentNodes(inputData.destinationNode);
checkNodes.push(inputData.destinationNode);
} else if (inputData.startNode) {
// If a start node is given we have to check all nodes which
// come after it
checkNodes = this.getChildNodes(inputData.startNode);
checkNodes.push(inputData.startNode);
}
for (const nodeName of checkNodes) {
nodeIssues = null;
node = this.nodes[nodeName];