- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
- Get Started
- Product
- Resources
- Tools & SDKs
- Framework
- Reference
4.8.4. Compensation Function
In this chapter, you'll learn what a compensation function is and how to add it to a step.
What is a Compensation Function#
A compensation function rolls back or undoes changes made by a step when an error occurs in the workflow.
For example, if a step creates a record, the compensation function deletes the record when an error occurs later in the workflow.
By using compensation functions, you provide a mechanism that guarantees data consistency in your application and across systems.
How to add a Compensation Function?#
A compensation function is passed as a second parameter to the createStep
function.
For example, create the file src/workflows/hello-world.ts
with the following content:
4} from "@medusajs/framework/workflows-sdk"5 6const step1 = createStep(7 "step-1",8 async () => {9 const message = `Hello from step one!`10 11 console.log(message)12 13 return new StepResponse(message)14 },15 async () => {16 console.log("Oops! Rolling back my changes...")17 }18)
Each step can have a compensation function. The compensation function only runs if an error occurs throughout the workflow.
Test the Compensation Function#
Create a step in the same src/workflows/hello-world.ts
file that throws an error:
Then, create a workflow that uses the steps:
Finally, execute the workflow from an API route:
Run the Medusa application and send a GET
request to /workflow
:
In the console, you'll see:
Hello from step one!
logged in the terminal, indicating that the first step ran successfully.Oops! Rolling back my changes...
logged in the terminal, indicating that the second step failed and the compensation function of the first step ran consequently.
Pass Input to Compensation Function#
If a step creates a record, the compensation function must receive the ID of the record to remove it.
To pass input to the compensation function, pass a second parameter in the StepResponse
returned by the step.
For example:
1import { 2 createStep,3 StepResponse,4} from "@medusajs/framework/workflows-sdk"5 6const step1 = createStep(7 "step-1",8 async () => {9 return new StepResponse(10 `Hello from step one!`, 11 { message: "Oops! Rolling back my changes..." }12 )13 },14 async ({ message }) => {15 console.log(message)16 }17)
In this example, the step passes an object as a second parameter to StepResponse
.
The compensation function receives the object and uses its message
property to log a message.
Resolve Resources from the Medusa Container#
The compensation function receives an object second parameter. The object has a container
property that you use to resolve resources from the Medusa container.
For example:
1import { 2 createStep,3 StepResponse,4} from "@medusajs/framework/workflows-sdk"5import { ContainerRegistrationKeys } from "@medusajs/framework/utils"6 7const step1 = createStep(8 "step-1",9 async () => {10 return new StepResponse(11 `Hello from step one!`, 12 { message: "Oops! Rolling back my changes..." }13 )14 },15 async ({ message }, { container }) => {16 const logger = container.resolve(17 ContainerRegistrationKeys.LOGGER18 )19 20 logger.info(message)21 }22)
In this example, you use the container
property in the second object parameter of the compensation function to resolve the logger.
You then use the logger to log a message.