diff --git a/server-node/src/routes/api/workflow-controller.ts b/server-node/src/routes/api/workflow-controller.ts index b790944bc..a84e42f20 100644 --- a/server-node/src/routes/api/workflow-controller.ts +++ b/server-node/src/routes/api/workflow-controller.ts @@ -20,8 +20,17 @@ router.post("/:workflowUuid?", [ return; } - // TODO: Validate input further (json may be invalid or not be in workflow format) - const workflow = JSON.parse(req.body.workflow); + try { + var workflow = JSON.parse(req.body.workflow); + } catch (err) { + if (err instanceof Error) { + console.error("malformed workflow-json was provided", err.message); + res.status(400).json({error: "Malformed workflow-JSON was provided. See Server-Logs for more info", details: err.message}); + return; + } else { + throw err; + } + } // TODO: Replace with static multer function of pdffile const inputs = await Promise.all((req.files as Express.Multer.File[]).map(async file => { @@ -32,12 +41,17 @@ router.post("/:workflowUuid?", [ if(req.body.async === "false") { console.log("Don't do async"); - let pdfResults = await traverseOperations(workflow.operations, inputs, (state) => { + traverseOperations(workflow.operations, inputs, (state) => { console.log("State: ", state); + }).then(async (pdfResults) => { + console.log("Download"); + await respondWithPdfFiles(res, pdfResults, "workflow-results"); + }).catch((err) => { + if(err.validationError) + res.status(400).json({error: err}); + else + throw err; }) - - console.log("Download"); - await respondWithPdfFiles(res, pdfResults, "workflow-results"); } else { console.log("Start Aync Workflow"); @@ -63,6 +77,7 @@ router.post("/:workflowUuid?", [ } }); + // TODO: Handle when this throws errors let pdfResults = await traverseOperations(workflow.operations, inputs, (state) => { console.log("State: ", state); if(activeWorkflow.eventStream) diff --git a/shared-operations/src/workflow/traverseOperations.ts b/shared-operations/src/workflow/traverseOperations.ts index 4c459d2e5..fbf1bf139 100644 --- a/shared-operations/src/workflow/traverseOperations.ts +++ b/shared-operations/src/workflow/traverseOperations.ts @@ -6,11 +6,11 @@ import { validateOperations } from "./validateOperations"; import { getOperatorByName } from "./getOperatorByName"; export async function traverseOperations(operations: Action[], input: PdfFile[], progressCallback: (state: Progress) => void): Promise { - - const validationResult = validateOperations(operations) + const validationResult = validateOperations(operations); if(!validationResult.valid) { - throw Error(validationResult.reason); + return Promise.reject({validationError: validationResult.reason}); } + const waitOperations = organizeWaitOperations(operations); let results: PdfFile[] = []; diff --git a/shared-operations/src/workflow/validateOperations.ts b/shared-operations/src/workflow/validateOperations.ts index 2d3bd2f6f..653d41b85 100644 --- a/shared-operations/src/workflow/validateOperations.ts +++ b/shared-operations/src/workflow/validateOperations.ts @@ -1,16 +1,35 @@ import { Action } from "../../declarations/Action"; +import { getOperatorByName } from "./getOperatorByName"; export function validateOperations(actions: Action[]): { valid: boolean, reason?: string} { - // TODO: Validate using inbuilt validators: - /* - validationResult = impose.validate() - if(validationResult.valid) { - // Check Next - } - else { - return validationResult.reason - } - */ + function validateOperation(actions: Action[]): { valid: boolean; reason?: string; } { + for (const action of actions) { + if (action.type === "wait" || action.type === "done") { + // TODO: Validate these too ): + return { valid: true }; + } + else { + const operator = getOperatorByName(action.type); + if(!operator) { + return { valid: false, reason: `action.type ${action.type} does not exist` } + } + const validationResult = new operator(action).validate(); + + if(!validationResult.valid) { + return validationResult; + } + } - return { valid: true }; + if (action.actions) { + const validationResult = validateOperation(action.actions); + + if(!validationResult.valid) { + return validationResult; + } + } + } + return { valid: true }; + } + + return validateOperation(actions); } \ No newline at end of file