0

I have this code where I use ReaderTaskEither:

export const AddUserToTeam = ({ userId, teamId }: AddUserToTeamDto) => {
    return pipe(
        //  Uses ReaderTaskEither
        Do,
        bind("deps", () => ask<Deps>()),
        bind("tx", ({ deps }) => fromTask(deps.createTransaction())),
        bind("addToTeams", ({ deps, tx }) => {
            return fromTaskEither(
                // ...
            );
        }),
        bindW("result", ({ deps, tx }) => {
            return fromTaskEither(
                deps.dispatcher.create(
                    // ...
                )({ tx })
            );
        }),
    );
};

and I create an interactive transaction (tx) as part of the pipe. My problem is that I'd like to call rollback on tx in case there was an error by using a fold or a mapLeft but I don't have access to the context that contains tx in either. How should I do this in order to retain a reference to tx somewhere?

Note that I can't make tx part of Deps because I'm not going to use transactions everywhere (they are opt-in).

Adam Arold
  • 29,285
  • 22
  • 112
  • 207

1 Answers1

1

You can do it in a "nested level", after you created tx. From you snippet:

export const AddUserToTeam = ({ userId, teamId }: AddUserToTeamDto) => {
  return pipe(
    Do,
    bind("deps", () => ask<Deps>()),
    bind("tx", ({ deps }) => fromTask(deps.createTransaction())),
    chain(({ deps, tx }) =>
      pipe(
        fromTaskEither(/*...*/),
        chain((addToTeams) =>
          fromTaskEither(deps.dispatcher.create(/*...*/)({ tx })),
        ),
        orElse((e) => fromTaskEither(tx.rollback())),
      ),
    ),
  );
};

I don't know what's the return type of tx.rollback, so I made it up.

Denis Frezzato
  • 957
  • 6
  • 15