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