Either

Either<V, E> is the type every endpoint returns. This page covers how to build one and what it offers.

E always implements the Error marker interface. NoFail is the built-in Error that means "this endpoint has no business failure". Its constructor is private, so a value of it can never actually be produced.

Either is a stopgap. Kotlin has no union types for errors yet, so there is no way to write "this returns an ArticleContent or an ArticleCreationFailure" as a type. Either stands in for that union until KT-68296: Union Types for Errors lands, at which point it will be replaced by a real union type and removed from the library. Do not build your own abstractions on top of it.

Building one

Either.value(articleSummaries)                    // a success
Either.error(ArticleCreationFailure.InvalidTitle)  // a business failure
Either.unit<ArticleCommentFailure>()               // shorthand for Either.value(Unit)

Reading one

Function Behaviour

on(value, error)

Folds both branches down to one result type.

valueOr { }

The value, or the block applied to the error.

mapValue { }

Transforms V, passing an error through unchanged.

mapError { }

Transforms E, passing a value through unchanged.

isValue() / isError()

Which branch this Either holds.

valueOrNull() / errorOrNull()

The value/error if this Either holds it, else null.

onValue { } / onError { }

Runs a side effect on the matching branch; returns the Either unchanged.

value() / error()

The value/error, throwing if this Either holds the other branch.

Every function above is inline, reified over V/E from the call site. Each also has a plain, non-reified overload taking an explicit NType<V>()/NType<E>(), for the rare call site where the type cannot be reified.

A when exhausted over every other Error subtype can dispatch the impossible NoFail case to it.isImpossible(): Nothing.