add extraction block json validation (#3499)

Co-authored-by: Shuchang Zheng <wintonzheng0325@gmail.com>
This commit is contained in:
Zara Cook
2025-09-27 02:36:14 -04:00
committed by GitHub
parent 90096bc453
commit 11d4518369
3 changed files with 100 additions and 12 deletions

View File

@@ -79,6 +79,8 @@ import {
getWorkflowSettings,
layout,
} from "./workflowEditorUtils";
import { getWorkflowErrors } from "./workflowEditorUtils";
import { toast } from "@/components/ui/use-toast";
import { useAutoPan } from "./useAutoPan";
const nextTick = () => new Promise((resolve) => setTimeout(resolve, 0));
@@ -373,8 +375,25 @@ function FlowRenderer({
setGetSaveDataRef.current(constructSaveData);
}, [constructSaveData]);
async function handleSave() {
return await saveWorkflow.mutateAsync();
async function handleSave(): Promise<boolean> {
// Validate before saving; block if any workflow errors exist
const errors = getWorkflowErrors(nodes);
if (errors.length > 0) {
toast({
title: "Can not save workflow because of errors:",
description: (
<div className="space-y-2">
{errors.map((error) => (
<p key={error}>{error}</p>
))}
</div>
),
variant: "destructive",
});
return false;
}
await saveWorkflow.mutateAsync();
return true;
}
function deleteNode(id: string) {
@@ -605,8 +624,10 @@ function FlowRenderer({
</Button>
<Button
onClick={() => {
handleSave().then(() => {
blocker.proceed?.();
handleSave().then((ok) => {
if (ok) {
blocker.proceed?.();
}
});
}}
disabled={workflowChangesStore.saveIsPending}

View File

@@ -2186,6 +2186,14 @@ function getWorkflowErrors(nodes: Array<AppNode>): Array<string> {
} catch {
errors.push(`${node.data.label}: Error messages is not valid JSON.`);
}
// Validate Task data schema JSON when enabled (value different from "null")
if (node.data.dataSchema && node.data.dataSchema !== "null") {
try {
JSON.parse(node.data.dataSchema);
} catch {
errors.push(`${node.data.label}: Data schema is not valid JSON.`);
}
}
});
const validationNodes = nodes.filter(isValidationNode);
@@ -2217,6 +2225,14 @@ function getWorkflowErrors(nodes: Array<AppNode>): Array<string> {
if (node.data.dataExtractionGoal.length === 0) {
errors.push(`${node.data.label}: Data extraction goal is required.`);
}
// Validate Extraction data schema JSON when enabled (value different from "null")
if (node.data.dataSchema && node.data.dataSchema !== "null") {
try {
JSON.parse(node.data.dataSchema);
} catch {
errors.push(`${node.data.label}: Data schema is not valid JSON.`);
}
}
});
const textPromptNodes = nodes.filter(isTextPromptNode);