# Passing parameters dynamically to Saga Compensation activities

**URL:** https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456
**Category:** Community Support
**Created:** [November 11, 2022, 7:06am UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456 "2022-11-11T07:06:14Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Prats](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/prats/32/1781_2.png) [@Prats](https://community.temporal.io/u/Prats)
#### Post date: [November 11, 2022, 7:06am UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/1 "2022-11-11T07:06:14Z")

</div>

We have a scenario where we would like to call saga compensation activity in case of failure and termination(using cancellation scope) as well. Is there a way to pass this status(failure/terminated) dynamically to saga compensation activity. Reason being, we have different tasks to finish based on the status.

for eg:

```auto
try {
      activityCancellationScope = Workflow.newCancellationScope(
          () -> {
            String carReservationID = activities.reserveCar(name);
            saga.addCompensation(activities::handleCarBooking, statusCode, name);
            String flightReservationID = activities.bookFlight(name);
            saga.addCompensation(activities::handleFlightBooking, statusCode, name);
            String hotelReservationID = activities.bookHotel(name);
            saga.addCompensation(activities::handleHotelBooking, statusCode, name);
          });
      activityCancellationScope.run();
    } catch (ActivityFailure e) {
      if(e.getCause() instanceof CanceledFailure) {
        status = "Terminated"; //is there a way to get this dynamically passed
        Workflow.newDetachedCancellationScope(() -> saga.compensate()).run();
      }
      status = "Failed";
      Workflow.newDetachedCancellationScope(() -> saga.compensate()).run();
      throw e;
    }

```

---

<div class="post-metadata">

### Author: ![tihomir](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/tihomir/32/6580_2.png) [@tihomir](https://community.temporal.io/u/tihomir)
#### Post date: [November 11, 2022, 3:59pm UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/2 "2022-11-11T15:59:54Z")

</div>

For activity invocation you can make compensation decision based on cause of ActivityFailure as you have shown. Can check for cause `ApplicationFailure` (through which you can get the failure thrown in your activity), `TimeoutFailure` (in case of activity timeout), `CanceledFailure` in case of cancellation.

Workflow termination is done on the server side and you won’t be able to handle that within wf code. Don’t make termination part of your business logic (use cancellation).

---

<div class="post-metadata">

### Author: ![Prats](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/prats/32/1781_2.png) [@Prats](https://community.temporal.io/u/Prats)
#### Post date: [November 15, 2022, 12:50pm UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/3 "2022-11-15T12:50:13Z")

</div>

I got the first part, not quite sure about the second part.

Let me rephrase my question.

In case of failure, I need to call certain set of clean up activities and for termination I need to call a different set. So to accomplish this, do I need to register two sagas as below or is it possible with one saga where we can pass Terminated/Failed status dynamically.

```auto
try {
      activityCancellationScope = Workflow.newCancellationScope(
          () -> {
            String carReservationID = activities.reserveCar(name);
            failureSaga.addCompensation(activities::handleCarBooking, "FAILED", name);
            terminationSaga.addCompensation(activities::handleCarBooking, "TERMINATED", name);
          });
      activityCancellationScope.run();
    } catch (ActivityFailure e) {
      if(e.getCause() instanceof CanceledFailure) {
        Workflow.newDetachedCancellationScope(() -> terminationSaga.compensate()).run();
      }
    
      Workflow.newDetachedCancellationScope(() -> failureSaga.compensate()).run();
      throw e;
    }

```

---

<div class="post-metadata">

### Author: ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)
#### Post date: [November 15, 2022, 4:36pm UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/4 "2022-11-15T16:36:00Z")

</div>

This is not possible with the Temporal definition of termination. Termination is an operation that is _intentionally_ a hard stop that precludes running any cleanup logic. The solution is not to use termination for normal business operations. Use cancellation instead.

It is like asking Linux to run some code in your application as a reaction to `kill -9`.

---

<div class="post-metadata">

### Author: ![Prats](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/prats/32/1781_2.png) [@Prats](https://community.temporal.io/u/Prats)
#### Post date: [November 16, 2022, 8:08am UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/5 "2022-11-16T08:08:13Z")

</div>

Currently we are indeed using cancellation scope for termination. In the catch block, as @tihomir mentioned we are able to differentiate between Timeout and Canceled Failures as well. So, my only question was how can we pass the type of failure(Timeout/Canceled) to saga compensation activity. @maxim Do you mean to say it’s not possible?

Also, I have one more question for you. We are planning to use Saga pattern in Java SDK. Could you please confirm if this is going to be supported long time? Hope it’s not an experimental feature.

---

<div class="post-metadata">

### Author: ![tihomir](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/tihomir/32/6580_2.png) [@tihomir](https://community.temporal.io/u/tihomir)
#### Post date: [November 16, 2022, 1:37pm UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/6 "2022-11-16T13:37:13Z")

</div>

> Could you please confirm if this is going to be supported long time?

Compensation (saga) impl is [included in the SDK](https://github.com/temporalio/sdk-java/blob/master/temporal-sdk/src/main/java/io/temporal/workflow/Saga.java) there shouldn’t be plans to remove it for some reason. You can extend this impl and add custom logic if needed as well.

> how can we pass the type of failure(Timeout/Canceled) to saga compensation activity

Without extending the saga impl I think you could have two separate Saga objects in your workflow and then call compensate on one or the other depending on the type of failure you catch in workflow code.  
If you need to pass the failure inputs to your compensation activities, you could `addCompensation` in your catch block and pass the failure message and type to the compensation activity.

---

<div class="post-metadata">

### Author: ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)
#### Post date: [November 16, 2022, 4:45pm UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/7 "2022-11-16T16:45:23Z")

</div>

Your options:

- Inside the compensation closures you can access any workflow variables to change the compensation logic dynamically.
- Create two Saga objects, one per failure type.
- Clone [Saga.java](https://github.com/temporalio/sdk-java/blob/37a0e463fae2312882b5c946f423a0dbf85f9666/temporal-sdk/src/main/java/io/temporal/workflow/Saga.java) and modify it to add an argument to `Saga.compensate`. Then pass this argument to each compensation callback.

---

<div class="post-metadata">

### Author: ![Prats](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/prats/32/1781_2.png) [@Prats](https://community.temporal.io/u/Prats)
#### Post date: [November 18, 2022, 2:04am UTC](https://community.temporal.io/t/passing-parameters-dynamically-to-saga-compensation-activities/6456/8 "2022-11-18T02:04:57Z")

</div>

@tihomir , @maxim Thank you so much for the info, much appreciated.
