I'm using the new parZipOrAccumulate
function from Arrow 1.2.0-RC to parallelize two calls and accumulate their errors if any:
private suspend fun getUser(legalId: UserLegalId): Either<ApplicationError, User>
private suspend fun getDepartment(departmentCode: DepartmentCode): Either<ApplicationError, Department>
override suspend fun execute(param: AddUserToDepartmentInfo): Either<Nel<ApplicationError>, Department> = either {
val pair: Pair<User, Department> =
parZipOrAccumulate<ApplicationError, User, Department, Pair<User, Department>>(
{e1: ApplicationError, e2 : ApplicationError-> nonEmptyListOf(e1,e2)},
{ getUser(param.userLegalId).bind() },
{ getDepartment(param.departmentCode).bind() }
) { a, b -> Pair(a, b) }
saveUserDrivenPort.save(pair.first.copy(departmentId = param.departmentCode)).bind()
pair.second
}
None of the three .bind()
calls in the code above compile because it expects the error types to match (ApplicationError
<-> Nel<ApplicationError>
).
How can I accumulate errors in a Nel<ApplicationError>
when I need to bind functions that may fail with an ApplicationError
?
As answered in this related question we can get rid of the combinator function and the errors will be automatically added to a Nel.
override suspend fun execute(param: AddUserToDepartmentInfo): Either<Nel<ApplicationError>, Department> = either {
val pair: Pair<User, Department> =
parZipOrAccumulate(
{ getUser(param.userLegalId).bind() },
{ getDepartment(param.departmentCode).bind() }
) { a, b -> Pair(a, b) }
saveUserDrivenPort.save(pair.first.copy(departmentId = param.departmentCode)).mapLeft { nonEmptyListOf(it) }.bind()
pair.second
}