From b0d0e7b1a691f952b0f511b172653cfaae0ef5e4 Mon Sep 17 00:00:00 2001 From: Shahed Nasser Date: Fri, 1 Aug 2025 11:54:41 +0300 Subject: [PATCH] docs: updates to nested workflow docs (#13117) --- .../execute-another-workflow/page.mdx | 76 +++++++++++++------ .../workflows/long-running-workflow/page.mdx | 1 + www/apps/book/generated/edit-dates.mjs | 4 +- www/apps/book/generated/sidebar.mjs | 4 +- www/apps/book/public/llms-full.txt | 59 ++++++++++---- www/apps/book/sidebar.mjs | 2 +- 6 files changed, 102 insertions(+), 44 deletions(-) diff --git a/www/apps/book/app/learn/fundamentals/workflows/execute-another-workflow/page.mdx b/www/apps/book/app/learn/fundamentals/workflows/execute-another-workflow/page.mdx index cd85aa8ed6..2b6b17b5af 100644 --- a/www/apps/book/app/learn/fundamentals/workflows/execute-another-workflow/page.mdx +++ b/www/apps/book/app/learn/fundamentals/workflows/execute-another-workflow/page.mdx @@ -1,16 +1,18 @@ export const metadata = { - title: `${pageNumber} Execute Another Workflow`, + title: `${pageNumber} Execute Nested Workflows`, } # {metadata.title} -In this chapter, you'll learn how to execute a workflow in another. +In this chapter, you'll learn how to execute a workflow in another workflow. -## Execute in a Workflow +## How to Execute a Workflow in Another? -To execute a workflow in another, use the `runAsStep` method that every workflow has. +In many cases, you may have a workflow that you want to re-use in another workflow. This is most common when you build custom workflows and you want to utilize Medusa's [existing workflows](!resources!/medusa-workflows-reference). -For example: +Executing a workflow within another is slightly different from how you usually execute a workflow. Instead of invoking the workflow, passing it the container, then running its `run` method, you use the `runAsStep` method of the workflow. This will pass the Medusa container and workflow context to the nested workflow. + +For example, to execute the [createProductsWorkflow](!resources!/references/medusa-workflows/createProductsWorkflow) in your custom workflow: export const workflowsHighlights = [ ["11", "runAsStep", "Use the `runAsStep` method to run the workflow as a step."], @@ -41,21 +43,21 @@ const workflow = createWorkflow( ) ``` -Instead of invoking the workflow and passing it the container, you use its `runAsStep` method and pass it an object as a parameter. +The `runAsStep` method accepts an `input` property to pass input to the workflow. -The object has an `input` property to pass input to the workflow. +### Returned Data + +Notice that you don't need to use `await` when executing the nested workflow, as it's not a promise in this scenario. + +You also receive the workflow's output as a return value from the `runAsStep` method. This is different from the usual workflow response, where you receive the output in a `result` property. --- -## Preparing Input Data +## Prepare Input Data -If you need to perform some data manipulation to prepare the other workflow's input data, use `transform` from the Workflows SDK. +Since Medusa creates an internal representation of your workflow's constructor function, you can't manipulate data directly in the workflow constructor. You can learn more about this in the [Data Manipulation](../variable-manipulation/page.mdx) chapter. - - -Learn about transform in [this chapter](../variable-manipulation/page.mdx). - - +If you need to perform some data manipulation to prepare the nested workflow's input data, use `transform` from the Workflows SDK. For example: @@ -99,25 +101,25 @@ const workflow = createWorkflow( ) ``` -In this example, you use the `transform` function to prepend `Hello` to the title of the product. Then, you pass the result as an input to the `createProductsWorkflow`. +In this example, you use the `transform` function to prepend `Hello` to the title of the product. Then, you pass the result as input to the `createProductsWorkflow`. + + + +Learn more about `transform` in the [Data Manipulation](../variable-manipulation/page.mdx) chapter. + + --- ## Run Workflow Conditionally -To run a workflow in another based on a condition, use when-then from the Workflows SDK. - - - -Learn about when-then in [this chapter](../conditions/page.mdx). - - +Similar to the [previous section](#prepare-input-data), you can't use conditional statements directly in the workflow constructor. Instead, you can use the `when-then` function from the Workflows SDK to run a workflow conditionally. For example: export const whenHighlights = [ ["20", "when", "If `should_create` passed in the input is enabled, then run the function passed to `then`."], - ["22", "createProductsWorkflow", "Workflow only runs if `when`'s condition is `true`."] + ["22", "createProductsWorkflow", "The workflow only runs if `when`'s condition is `true`."] ] ```ts highlights={whenHighlights} collapsibleLines="1-16" @@ -152,4 +154,30 @@ const workflow = createWorkflow( ) ``` -In this example, you use when-then to run the `createProductsWorkflow` only if `should_create` (passed in the `input`) is enabled. +In this example, you use `when-then` to run the `createProductsWorkflow` only if `should_create` (passed in the `input`) is enabled. + + + +Learn more about `when-then` in the [When-Then Conditions](../conditions/page.mdx) chapter. + + + +--- + +## Errors in Nested Workflows + +A nested workflow behaves similarly to a step in a workflow. So, if the nested workflow fails, it will throw an error that stops the parent workflow's execution and compensates previous steps. + +In addition, if another step fails after the nested workflow, the nested workflow's steps will be compensated as part of the compensation process. + +Learn more about handling errors in workflows in the [Error Handling](../errors/page.mdx) chapter. + +--- + +## Nested Long-Running Workflows + +When you execute a long-running workflow within another workflow, the parent workflow becomes a long-running workflow as well. + +So, the parent workflow will wait for the nested workflow to finish before continuing its execution. + +Refer to the [Long-Running Workflows](../long-running-workflow/page.mdx) chapter for more information on how to handle long-running workflows. \ No newline at end of file diff --git a/www/apps/book/app/learn/fundamentals/workflows/long-running-workflow/page.mdx b/www/apps/book/app/learn/fundamentals/workflows/long-running-workflow/page.mdx index ab1577a880..ec021b18a1 100644 --- a/www/apps/book/app/learn/fundamentals/workflows/long-running-workflow/page.mdx +++ b/www/apps/book/app/learn/fundamentals/workflows/long-running-workflow/page.mdx @@ -82,6 +82,7 @@ A workflow is also considered long-running if: - One of its steps has its `async` configuration set to `true` and doesn't return a step response. - One of its steps has its `retryInterval` option set as explained in the [Retry Failed Steps chapter](../retry-failed-steps/page.mdx). +- One of its [nested workflows](../execute-another-workflow/page.mdx) is a long-running workflow. --- diff --git a/www/apps/book/generated/edit-dates.mjs b/www/apps/book/generated/edit-dates.mjs index 2d93665ad3..cf2b51549a 100644 --- a/www/apps/book/generated/edit-dates.mjs +++ b/www/apps/book/generated/edit-dates.mjs @@ -17,7 +17,7 @@ export const generatedEditDates = { "app/learn/fundamentals/modules/modules-directory-structure/page.mdx": "2025-07-25T15:40:20.362Z", "app/learn/fundamentals/events-and-subscribers/page.mdx": "2025-05-16T13:40:16.111Z", "app/learn/fundamentals/modules/container/page.mdx": "2025-07-31T14:24:04.087Z", - "app/learn/fundamentals/workflows/execute-another-workflow/page.mdx": "2024-12-09T15:56:22.895Z", + "app/learn/fundamentals/workflows/execute-another-workflow/page.mdx": "2025-08-01T07:28:51.036Z", "app/learn/fundamentals/modules/loaders/page.mdx": "2025-06-16T13:34:16.462Z", "app/learn/fundamentals/admin/widgets/page.mdx": "2025-07-25T15:08:07.035Z", "app/learn/fundamentals/data-models/page.mdx": "2025-03-18T07:55:56.252Z", @@ -30,7 +30,7 @@ export const generatedEditDates = { "app/learn/fundamentals/workflows/conditions/page.mdx": "2025-01-27T08:45:19.027Z", "app/learn/fundamentals/modules/module-link-directions/page.mdx": "2024-07-24T09:16:01+02:00", "app/learn/fundamentals/admin/page.mdx": "2025-07-25T12:46:15.466Z", - "app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2025-07-14T10:32:21.640Z", + "app/learn/fundamentals/workflows/long-running-workflow/page.mdx": "2025-08-01T07:16:21.736Z", "app/learn/fundamentals/workflows/constructor-constraints/page.mdx": "2025-04-24T13:18:24.184Z", "app/learn/fundamentals/data-models/write-migration/page.mdx": "2025-07-25T13:53:00.692Z", "app/learn/fundamentals/data-models/manage-relationships/page.mdx": "2025-04-25T14:16:41.124Z", diff --git a/www/apps/book/generated/sidebar.mjs b/www/apps/book/generated/sidebar.mjs index 0eea209e41..fe0ae55afd 100644 --- a/www/apps/book/generated/sidebar.mjs +++ b/www/apps/book/generated/sidebar.mjs @@ -840,9 +840,9 @@ export const generatedSidebars = [ "isPathHref": true, "type": "link", "path": "/learn/fundamentals/workflows/execute-another-workflow", - "title": "Execute Another Workflow", + "title": "Execute Nested Workflows", "children": [], - "chapterTitle": "3.7.13. Execute Another Workflow", + "chapterTitle": "3.7.13. Execute Nested Workflows", "number": "3.7.13." }, { diff --git a/www/apps/book/public/llms-full.txt b/www/apps/book/public/llms-full.txt index 63d03329c2..0c7819ac84 100644 --- a/www/apps/book/public/llms-full.txt +++ b/www/apps/book/public/llms-full.txt @@ -18840,15 +18840,17 @@ In this example, if the `actionThatThrowsError` step throws an error, the `moreA You can then access the error that occurred in that step as explained in the [Disable Error Throwing](#disable-error-throwing-in-workflow) section. -# Execute Another Workflow +# Execute Nested Workflows -In this chapter, you'll learn how to execute a workflow in another. +In this chapter, you'll learn how to execute a workflow in another workflow. -## Execute in a Workflow +## How to Execute a Workflow in Another? -To execute a workflow in another, use the `runAsStep` method that every workflow has. +In many cases, you may have a workflow that you want to re-use in another workflow. This is most common when you build custom workflows and you want to utilize Medusa's [existing workflows](https://docs.medusajs.com/resources/medusa-workflows-reference/index.html.md). -For example: +Executing a workflow within another is slightly different from how you usually execute a workflow. Instead of invoking the workflow, passing it the container, then running its `run` method, you use the `runAsStep` method of the workflow. This will pass the Medusa container and workflow context to the nested workflow. + +For example, to execute the [createProductsWorkflow](https://docs.medusajs.com/resources/references/medusa-workflows/createProductsWorkflow/index.html.md) in your custom workflow: ```ts highlights={workflowsHighlights} collapsibleLines="1-7" expandMoreButton="Show Imports" import { @@ -18874,17 +18876,21 @@ const workflow = createWorkflow( ) ``` -Instead of invoking the workflow and passing it the container, you use its `runAsStep` method and pass it an object as a parameter. +The `runAsStep` method accepts an `input` property to pass input to the workflow. -The object has an `input` property to pass input to the workflow. +### Returned Data + +Notice that you don't need to use `await` when executing the nested workflow, as it's not a promise in this scenario. + +You also receive the workflow's output as a return value from the `runAsStep` method. This is different from the usual workflow response, where you receive the output in a `result` property. *** -## Preparing Input Data +## Prepare Input Data -If you need to perform some data manipulation to prepare the other workflow's input data, use `transform` from the Workflows SDK. +Since Medusa creates an internal representation of your workflow's constructor function, you can't manipulate data directly in the workflow constructor. You can learn more about this in the [Data Manipulation](https://docs.medusajs.com/learn/fundamentals/workflows/variable-manipulation/index.html.md) chapter. -Learn about transform in [this chapter](https://docs.medusajs.com/learn/fundamentals/workflows/variable-manipulation/index.html.md). +If you need to perform some data manipulation to prepare the nested workflow's input data, use `transform` from the Workflows SDK. For example: @@ -18923,15 +18929,15 @@ const workflow = createWorkflow( ) ``` -In this example, you use the `transform` function to prepend `Hello` to the title of the product. Then, you pass the result as an input to the `createProductsWorkflow`. +In this example, you use the `transform` function to prepend `Hello` to the title of the product. Then, you pass the result as input to the `createProductsWorkflow`. + +Learn more about `transform` in the [Data Manipulation](https://docs.medusajs.com/learn/fundamentals/workflows/variable-manipulation/index.html.md) chapter. *** ## Run Workflow Conditionally -To run a workflow in another based on a condition, use when-then from the Workflows SDK. - -Learn about when-then in [this chapter](https://docs.medusajs.com/learn/fundamentals/workflows/conditions/index.html.md). +Similar to the [previous section](#prepare-input-data), you can't use conditional statements directly in the workflow constructor. Instead, you can use the `when-then` function from the Workflows SDK to run a workflow conditionally. For example: @@ -18967,7 +18973,29 @@ const workflow = createWorkflow( ) ``` -In this example, you use when-then to run the `createProductsWorkflow` only if `should_create` (passed in the `input`) is enabled. +In this example, you use `when-then` to run the `createProductsWorkflow` only if `should_create` (passed in the `input`) is enabled. + +Learn more about `when-then` in the [When-Then Conditions](https://docs.medusajs.com/learn/fundamentals/workflows/conditions/index.html.md) chapter. + +*** + +## Errors in Nested Workflows + +A nested workflow behaves similarly to a step in a workflow. So, if the nested workflow fails, it will throw an error that stops the parent workflow's execution and compensates previous steps. + +In addition, if another step fails after the nested workflow, the nested workflow's steps will be compensated as part of the compensation process. + +Learn more about handling errors in workflows in the [Error Handling](https://docs.medusajs.com/learn/fundamentals/workflows/errors/index.html.md) chapter. + +*** + +## Nested Long-Running Workflows + +When you execute a long-running workflow within another workflow, the parent workflow becomes a long-running workflow as well. + +So, the parent workflow will wait for the nested workflow to finish before continuing its execution. + +Refer to the [Long-Running Workflows](https://docs.medusajs.com/learn/fundamentals/workflows/long-running-workflow/index.html.md) chapter for more information on how to handle long-running workflows. # Long-Running Workflows @@ -19048,6 +19076,7 @@ A workflow is also considered long-running if: - One of its steps has its `async` configuration set to `true` and doesn't return a step response. - One of its steps has its `retryInterval` option set as explained in the [Retry Failed Steps chapter](https://docs.medusajs.com/learn/fundamentals/workflows/retry-failed-steps/index.html.md). +- One of its [nested workflows](https://docs.medusajs.com/learn/fundamentals/workflows/execute-another-workflow/index.html.md) is a long-running workflow. *** diff --git a/www/apps/book/sidebar.mjs b/www/apps/book/sidebar.mjs index 81c8c90cc0..5b5661305b 100644 --- a/www/apps/book/sidebar.mjs +++ b/www/apps/book/sidebar.mjs @@ -441,7 +441,7 @@ export const sidebars = [ { type: "link", path: "/learn/fundamentals/workflows/execute-another-workflow", - title: "Execute Another Workflow", + title: "Execute Nested Workflows", }, { type: "link",