vjames19
04/29/2020, 10:11 PMimport 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?streetsofboston
04/29/2020, 11:03 PMsealed 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.