getOrThrow?
efenderbosch opened this issue · comments
This can be useful at boundaries, like a rest or graphql handler. I've added an extension function, but this might be useful in the core library. I did a quick search and didn't find any related issues.
fun <V, E> Result<V, E>.getOrThrow(transform : (E) -> Throwable): V = getOrElse { error -> throw transform(error) }
edit: right now I'm using all of these.
fun <V, E> Result<V, E>.getOrThrow(transform: (E) -> Throwable) = getOrElse { throw transform(it) }
fun <V: Any?> V.success() = Ok(this)
fun <E: Any?> E.failure() = Err(this)
inline fun <V: Any, reified E: Throwable> trying(noinline block: () -> V) = trying(E::class, block)
fun <V, E: Throwable> trying(klass: KClass<E>, block: () -> V): Result<V, E> = try {
block().success()
} catch (e: Throwable) {
@Suppress("UNCHECKED_CAST")
when {
klass.isInstance(e) -> e.failure() as Err<E>
else -> throw e
}
}
Thanks for your suggestions.
orElseThrow
should fit your use case (you can mapErr
the failure state to a Throwable, then call orElseThrow
).
Your trying
is mostly the same as runCatching
. Not a huge fan of the isInstance
check going on in the catch
statement though.
Yeah, neither am I. Any suggestions on how to fix that?
Just saw that orElseThrow
got added a few months ago. We've previously built a custom getOrThrow
as well
fun <T> Result<T, Exception>.getOrThrow(): T =
this.mapBoth({ it }, { throw it })
The most important distinction from orElseThrow
is the user being able to instantly use the Ok
value, without another call to unwrap
(or the raw use of the value
property of the Ok
type) being needed. As @efenderbosch mentioned, the use case for this is a boundary to e.g. a framework, in our case Spring @Scheduled
functions.
It would certainly be nice to have first party support in the library for this.
Seems like it's in the stdlib Result, so probably worth adding. Will accept a PR, or get around to it in the new year otherwise.