Search code examples
typescriptfp-ts

How to get access to a variable in a ReaderTaskEither from an error handling function using fp-ts?


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).


Solution

  • 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.