michaelbull / kotlin-result

A multiplatform Result monad for modelling success or failure operations.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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.