Create Element
Element Error Detection
Learn how to extend the function used to detect failures in the workflow.
Element Error Detection
To add the failure-detection logic for the new element, we'll update the file shown below:
// src/shared/kits/workflow/utilities/validate.ts
import type {
Workflow,
ElementFlow,
ActionFlow,
ConditionFlow,
SwitchFlow,
LoopFlow,
ParallelFlow,
Failure,
} from "../mvc/model/workflow";
export function validate(workflow: Workflow): Failure | null {
if (workflow.flow.start.message === "") {
return {
type: "start",
node: "start",
message: "It can't be empty",
};
}
if (workflow.flow.elements.length === 0) {
return {
type: "addTop",
node: "addTop",
message: "At least one element is required",
};
}
for (const element of workflow.flow.elements) {
const failure = validateElement(element);
if (failure) return failure;
}
if (workflow.flow.end.message === "") {
return {
type: "end",
node: "end",
message: "It can't be empty",
};
}
return null;
}
function validateElement(element: ElementFlow): Failure | null {
switch (element.type) {
case "action":
return validateAction(element);
case "condition":
return validateCondition(element);
case "switch":
return validateSwitch(element);
case "loop":
return validateLoop(element);
case "parallel":
return validateParallel(element);
}
}
function validateAction(element: ActionFlow): Failure | null {
if (element.message === "") {
return {
type: "element",
element: "action",
id: element.id,
node: `${element.id}/flow/block`,
message: "It can't be empty",
};
}
return null;
}
function validateCondition(element: ConditionFlow): Failure | null {
if (element.if === "") {
return {
type: "element",
element: "condition",
id: element.id,
node: `${element.id}/flow/block`,
message: "It can't be empty",
};
}
for (const thenElement of element.then) {
const failure = validateElement(thenElement);
if (failure) return failure;
}
for (const elseElement of element.else) {
const failure = validateElement(elseElement);
if (failure) return failure;
}
return null;
}
function validateSwitch(element: SwitchFlow): Failure | null {
for (let i = 0; i < element.branches.length; i++) {
const branch = element.branches[i];
if (branch.case === "") {
return {
type: "element",
element: "switch",
id: element.id,
branch: i,
node: `${element.id}/flow/blockBranch/${i}`,
message: "It can't be empty",
};
}
for (const branchElement of branch.then) {
const failure = validateElement(branchElement);
if (failure) return failure;
}
}
for (const defaultElement of element.default) {
const failure = validateElement(defaultElement);
if (failure) return failure;
}
return null;
}
function validateLoop(element: LoopFlow): Failure | null {
if (element.while === "") {
return {
type: "element",
element: "loop",
id: element.id,
node: `${element.id}/flow/block`,
message: "It can't be empty",
};
}
for (const intoElement of element.into) {
const failure = validateElement(intoElement);
if (failure) return failure;
}
return null;
}
function validateParallel(element: ParallelFlow): Failure | null {
for (let i = 0; i < element.branches.length; i++) {
const branch = element.branches[i];
if (branch.label === "") {
return {
type: "element",
element: "parallel",
id: element.id,
branch: i,
node: `${element.id}/flow/blockBranch/${i}`,
message: "It can't be empty",
};
}
for (const branchElement of branch.then) {
const failure = validateElement(branchElement);
if (failure) return failure;
}
}
return null;
}