Hi! I'm really interested in functional error han...
# arrow
v
Hi! I'm really interested in functional error handling and the benefits that it brings by being explicit on the types of errors that can happen on each function. https://arrow-kt.io/docs/0.10/patterns/error_handling/ The example below showcases a generic example of different functions that implement some business logic and each has its own Set of distinct errors that can happen. These functions would later be use for implementing use cases, in which the use cases could also be reused across other use cases. I'm struggling to understand how to combine errors without losing type information and without having to resort to creating wrapper classes for each combination of errors.
Copy code
import arrow.core.Either

// fictitious domain
sealed class BusinessLogic1Error { 
  // all errors
}

sealed class BusinessLogic2Error {
  // all errors
}

sealed class BusinessLogic3Error {
  // all errors
}

fun businessLogic1(): Either<BusinessLogic1Error, String> = TODO()
fun businessLogic2(): Either<BusinessLogic2Error, String> = TODO()
fun businessLogic3(): Either<BusinessLogic3Error, String> = TODO()


// use cases that use different business logic

// approach 1
// Union Type through wrapper class

sealed class UseCaseError {
  class BusinessLogic1(val businessLogic1Error: BusinessLogic1Error): UseCaseError()
  class BusinessLogic2(val businessLogic2Error: BusinessLogic2Error): UseCaseError()
  // any other error that can be generated by a function used by this use case
  
}
fun useCase(): Either<UseCaseError, String> = TODO()

// Pros:
// Explicit and doesn't lose type information
// Cons:
// Doing this across multiple use cases gets unwieldy


// approach 2
fun useCase(): Either<Throwable, String> = TODO()

// Loses all type info and its only serving as a placeholder to say that the function can fail
Am I missing something? Is there a better approach?
s
You can have a sealed class extend another sealed class. Eg in your first example, all your BusinessLogicXError classes could extend
sealed class UseCaseError
. Of course, this would require all errors to be declared in one file. If they are spread out over multiple files,
UseCaseError
cannot be sealed and is just abstract/open or an interface.