payload
Version:
Node, React, Headless CMS and Application Framework built on Next.js
126 lines (125 loc) • 4.52 kB
JavaScript
// @ts-strict-ignore
import { getRunTaskFunction } from '../runJob/getRunTaskFunction.js';
import { handleWorkflowError } from '../runJob/handleWorkflowError.js';
export const runJSONJob = async ({ job, req, updateJob, workflowConfig, workflowHandler })=>{
// Object so that we can pass contents by reference, not value.
// We want any mutations to be reflected in here.
const state = {
reachedMaxRetries: false
};
const stepsToRun = [];
for (const step of workflowHandler){
if ('task' in step) {
if (job?.taskStatus?.[step.task]?.[step.id]?.complete) {
continue;
}
} else {
if (job?.taskStatus?.['inline']?.[step.id]?.complete) {
continue;
}
}
if (step.condition && !step.condition({
job: job
})) {
continue;
}
stepsToRun.push(step);
}
const tasks = getRunTaskFunction(state, job, workflowConfig, req, false, updateJob);
const inlineTask = getRunTaskFunction(state, job, workflowConfig, req, true, updateJob);
// Run the job
let hasFinalError = false;
let error;
try {
await Promise.all(stepsToRun.map(async (step)=>{
if ('task' in step) {
await tasks[step.task](step.id, {
input: step.input ? step.input({
job: job
}) : {},
retries: step.retries
});
} else {
await inlineTask(step.id, {
retries: step.retries,
task: step.inlineTask
});
}
}));
} catch (err) {
const errorResult = handleWorkflowError({
error: err,
job,
req,
state,
workflowConfig
});
error = err;
hasFinalError = errorResult.hasFinalError;
}
// Check if workflow has completed
let workflowCompleted = false;
for (const [slug, map] of Object.entries(job.taskStatus)){
for (const [id, taskStatus] of Object.entries(map)){
if (taskStatus.complete) {
const step = workflowHandler.find((step)=>{
if ('task' in step) {
return step.task === slug && step.id === id;
} else {
return step.id === id && slug === 'inline';
}
});
if (step.completesJob) {
workflowCompleted = true;
break;
}
}
}
}
if (workflowCompleted) {
if (error) {
// Tasks update the job if they error - but in case there is an unhandled error (e.g. in the workflow itself, not in a task)
// we need to ensure the job is updated to reflect the error
await updateJob({
completedAt: new Date().toISOString(),
error: hasFinalError ? error : undefined,
hasError: hasFinalError,
processing: false,
totalTried: (job.totalTried ?? 0) + 1
});
} else {
await updateJob({
completedAt: new Date().toISOString(),
processing: false,
totalTried: (job.totalTried ?? 0) + 1
});
}
return {
status: 'success'
};
} else {
if (error) {
// Tasks update the job if they error - but in case there is an unhandled error (e.g. in the workflow itself, not in a task)
// we need to ensure the job is updated to reflect the error
await updateJob({
error: hasFinalError ? error : undefined,
hasError: hasFinalError,
processing: false,
totalTried: (job.totalTried ?? 0) + 1
});
return {
status: hasFinalError ? 'error-reached-max-retries' : 'error'
};
} else {
// Retry the job - no need to bump processing or totalTried as this does not count as a retry. A condition of a different task might have just opened up!
return await runJSONJob({
job,
req,
updateJob,
workflowConfig,
workflowHandler
});
}
}
};
//# sourceMappingURL=index.js.map