diff --git a/.changeset/plenty-ravens-lay.md b/.changeset/plenty-ravens-lay.md new file mode 100644 index 0000000000..07e26c142a --- /dev/null +++ b/.changeset/plenty-ravens-lay.md @@ -0,0 +1,5 @@ +--- +"@medusajs/workflows-sdk": patch +--- + +fix(workflows-sdk): Handle result from a trasnformer after a step fail diff --git a/packages/workflows-sdk/src/helper/workflow-export.ts b/packages/workflows-sdk/src/helper/workflow-export.ts index cfd1f54679..49af002e64 100644 --- a/packages/workflows-sdk/src/helper/workflow-export.ts +++ b/packages/workflows-sdk/src/helper/workflow-export.ts @@ -192,7 +192,7 @@ function createContextualWorkflowRunner< ) => { const transaction = await method.apply(method, args) - const errors = transaction.getErrors(TransactionHandlerType.INVOKE) + let errors = transaction.getErrors(TransactionHandlerType.INVOKE) const failedStatus = [TransactionState.FAILED, TransactionState.REVERTED] const isCancelled = @@ -211,7 +211,13 @@ function createContextualWorkflowRunner< let result if (options?.wrappedInput) { - result = await resolveValue(resultFrom, transaction.getContext()) + result = resolveValue(resultFrom, transaction.getContext()) + if (result instanceof Promise) { + result = await result.catch((e) => { + errors ??= [] + errors.push(e) + }) + } } else { result = transaction.getContext().invoke?.[resultFrom] } diff --git a/packages/workflows-sdk/src/utils/composer/__tests__/index.spec.ts b/packages/workflows-sdk/src/utils/composer/__tests__/index.spec.ts new file mode 100644 index 0000000000..1be1407ea9 --- /dev/null +++ b/packages/workflows-sdk/src/utils/composer/__tests__/index.spec.ts @@ -0,0 +1,41 @@ +import { createStep } from "../create-step" +import { StepResponse } from "../helpers" +import { createWorkflow } from "../create-workflow" +import { transform } from "../transform" + +describe("Workflow composer", () => { + it("should not throw an unhandled error on failed transformer resolution after a step fail, but should rather push the errors in the errors result", async function () { + const step1 = createStep("step1", async () => { + return new StepResponse({ result: "step1" }) + }) + const step2 = createStep("step2", async () => { + throw new Error("step2 failed") + }) + + const work = createWorkflow("id" as any, () => { + const resStep1 = step1() + const resStep2 = step2() + + const transformedData = transform({ data: resStep2 }, (data) => { + return { result: data.data.result } + }) + + return transform({ data: transformedData, resStep2 }, (data) => { + return { result: data.data } + }) + }) + + const { errors } = await work().run({ input: {}, throwOnError: false }) + + expect(errors).toEqual([ + { + action: "step2", + handlerType: "invoke", + error: new Error("step2 failed"), + }, + expect.objectContaining({ + message: "Cannot read properties of undefined (reading 'result')", + }), + ]) + }) +}) diff --git a/packages/workflows-sdk/src/utils/composer/create-workflow.ts b/packages/workflows-sdk/src/utils/composer/create-workflow.ts index 674ed887f2..c9f6b66964 100644 --- a/packages/workflows-sdk/src/utils/composer/create-workflow.ts +++ b/packages/workflows-sdk/src/utils/composer/create-workflow.ts @@ -5,7 +5,7 @@ import { WorkflowManager, } from "@medusajs/orchestration" import { LoadedModule, MedusaContainer } from "@medusajs/types" -import { OrchestrationUtils, isString } from "@medusajs/utils" +import { isString, OrchestrationUtils } from "@medusajs/utils" import { ExportedWorkflow, exportWorkflow } from "../../helper" import { proxify } from "./helpers/proxy" import {