Support for Saga compensating transactions in Typescript

Hello everyone :slightly_smiling_face:
I was wondering whether there is a way to support saga compensating transactions in Typescript?
If so, where can I find examples and best practices.

Welcome to the forum! Here’s a sample: samples-typescript/saga at main · temporalio/samples-typescript · GitHub

Sure! Workflows actually makes implementing saga-style compensation very easy. As a workflow is simply code, your compensation logic can be defined in the workflow itself, based on your language’s built-in exception handling mechanisms.

In TypeScript, for example, you will simply perform appropriate compensations from a catch block surrounding activities that could fail. Here is an example of how one might do it (this is by no mean the only way to do it):

export async function createAccount(...) {
  let address?: Address;
  let client?: Client;
  let bankAccount?: BankAccount;

  try {
    address = await addClient(...);
    client = await addClient(...);
    bankAccount = await addBankAccount(...);
  } catch (e) {
    // Do compensations here, depending on which elements had been created
    if (bankAccount) await removeBankAccount(...);
    if (client) await removeClient(...);
    if (address) await removeAddress(...);
    throw e;

For more complex scenarios, you may expand the principle exposed above to something more tailored to your specific use cases. For example, you might consider registering “compensation functions” into a collection after each completed activity; then, from the catch block, you would simply invoke each of these function, in reverse order. See samples-typescript/saga at main · temporalio/samples-typescript · GitHub for a demonstration of this strategy.

1 Like

Looks good. Thanks a lot :ok_hand: