Saga Pattern - Compensation for Partial Failure

Use Case
We have 3 activites
Book Hotel - Logically can Fail or Complete
Book Flowers - Logically can Fail or Complete or Partially Fail
Book Flight - Logically can Fail or Complete

In our current design, if an activity copletes, we add opposite of the completed activity to the saga bucket.
ex : if Book Hotel completes, we add cancel Hotel Booking to the saga bucket.

And when any of the next activity fails, we call compensate on the saga bucket.


What if the business logic inside the activity partially fails?
ex : In the order flowers activity, if we request to the end system for 100 flowers, but it was able to order only 50 flowers, then its a partial failure.
How to implement compensation in case of partial failure?

The examples in temporal github, only assumes completed or failure states only, There is not concept of partial success.

As part of compensation I wan to cancel the order of 50 flowers.

The solution we thought of

Partial Failure will be considered as Completed itself. ie: Even though we were able to order only 50 flowers, we will say the order flowers activity is completed. And add cancel flowers activity to saga bucket.

Then I will have another activity to validate if I was able to order all the flowers, if not it will fail.
When it fails, we invoke saga compensate and as part of compensation we cancel flower booking and cancel hotel booking.


Is there a better way to do thi?

There are intermittent and permanent failures. An activity failing in the middle of execution is an intermittent failure and should be dealt with by retrying the activity. Given that activity is idempotent then the failure should be handled seamlessly.

The business level failures are not really partial and can be reported cleanly through non retriable exceptions or activity results. The SAGA should really compensate only business level failures.