feat(ui): use templates for edge validation of workflows

This addresses an edge case where:
1. the workflow references fields that are present on the workflow's nodes, but not on the invocation templates for those nodes and
2. The invocation template for that type does exist

This should be a fairly obscure edge case, but could happen if a user fiddled around with the workflow manually.

I ran into it as a result of two nodes having accidentally mixed up their invocation types, a problem introduced with a wonky merge commit.
This commit is contained in:
psychedelicious 2023-12-06 20:42:34 +11:00
parent 13c9f8ffb7
commit db4763a742

View File

@ -86,6 +86,12 @@ export const validateWorkflow = (
// Validate each edge. If the edge is invalid, we must remove it to prevent runtime errors with reactflow.
const sourceNode = keyedNodes[edge.source];
const targetNode = keyedNodes[edge.target];
const sourceTemplate = sourceNode
? invocationTemplates[sourceNode.data.type]
: undefined;
const targetTemplate = targetNode
? invocationTemplates[targetNode.data.type]
: undefined;
const issues: string[] = [];
if (!sourceNode) {
@ -95,9 +101,23 @@ export const validateWorkflow = (
node: edge.source,
})
);
} else if (
}
if (!sourceTemplate) {
// The edge's source/output node template does not exist
issues.push(
t('nodes.missingTemplate', {
node: edge.source,
type: sourceNode?.data.type,
})
);
}
if (
sourceNode &&
sourceTemplate &&
edge.type === 'default' &&
!(edge.sourceHandle in sourceNode.data.outputs)
!(edge.sourceHandle in sourceTemplate.outputs)
) {
// The edge's source/output node field does not exist
issues.push(
@ -115,9 +135,23 @@ export const validateWorkflow = (
node: edge.target,
})
);
} else if (
}
if (!targetTemplate) {
// The edge's target/input node template does not exist
issues.push(
t('nodes.missingTemplate', {
node: edge.target,
type: targetNode?.data.type,
})
);
}
if (
targetNode &&
targetTemplate &&
edge.type === 'default' &&
!(edge.targetHandle in targetNode.data.inputs)
!(edge.targetHandle in targetTemplate.inputs)
) {
// The edge's target/input node field does not exist
issues.push(
@ -128,25 +162,6 @@ export const validateWorkflow = (
);
}
if (!sourceNode?.data.type || !invocationTemplates[sourceNode.data.type]) {
// The edge's source/output node template does not exist
issues.push(
t('nodes.missingTemplate', {
node: edge.source,
type: sourceNode?.data.type,
})
);
}
if (!targetNode?.data.type || !invocationTemplates[targetNode?.data.type]) {
// The edge's target/input node template does not exist
issues.push(
t('nodes.missingTemplate', {
node: edge.target,
type: targetNode?.data.type,
})
);
}
if (issues.length) {
// This edge has some issues. Remove it.
delete edges[i];