
Rust-style error handling with context-aware errors, a result builder, bind() short-circuiting, bail/ensure helpers, typed/untyped errors, rich contextual propagation, and converts existing Result values for seamless interop.
Rust-style error handling for Kotlin.
AnyhowKt is a Kotlin Multiplatform (KMP) library inspired by Rust's
anyhow crate. It provides a simple, powerful,
and expressive way to handle errors with:
bind() (Rust ?-like behavior)bail, ensure, and structured error propagationanyhow { } result builderbind() for early-return error propagation (Rust ?).context() and withContext() for rich error messagesbail() for immediate failureensure() / ensureNotNull() helpersResult to AnyhowResult
sourceSets {
commonMain.dependencies {
implementation("io.github.itsvks19:anyhowkt:<version>")
}
}dependencies {
implementation("io.github.itsvks19:anyhowkt:<version>")
}val result = anyhow {
val a = parseInt("10").bind()
val b = parseInt("20").bind()
a + b
}val value: Int = result.unwrap()Rust:
let value = compute()?;Kotlin (AnyhowKt):
val value = compute().bind()This works inside anyhow { } blocks.
val result = anyhow {
val file = readFile("config.json")
.anyhowResult { "file not found" }
.bind() // Early return on readFile failure
parseConfig(file)
.anyhow()
.bind()
}.context("Failed to load application config")Error output becomes:
Failed to load application config
Caused by: file not found
...
val result = anyhow {
if (user == null) {
bail("User not found")
}
user.name
}anyhow {
ensure(x > 0) { "x must be positive" }
ensureNotNull(user) { "user is required" }
ensureEquals(a, b) { "values must match" }
}val kResult: Result<Int> = runCatching { riskyCall() }
val result: AnyhowResult<Int> = kResult.anyhow()This library internally uses arrow-kt.
If you are using an IntelliJ IDEA or any other IDE from JetBrains, we strongly recommend installing the Arrow plug-in. The plug-in helps fix common problems, especially in the realm of typed errors and suggests more idiomatic alternatives when available.
Rust (anyhow) |
Kotlin (AnyhowKt) |
|---|---|
anyhow::Result<T> |
AnyhowResult<T> |
? |
.bind() |
bail!("msg") |
bail("msg") |
.context("msg") |
.context("msg") |
ensure!(cond) |
ensure(cond) |
MIT License.
PRs and feature requests are welcome! If you'd like to help add:
feel free to contribute ✨
Rust-style error handling for Kotlin.
AnyhowKt is a Kotlin Multiplatform (KMP) library inspired by Rust's
anyhow crate. It provides a simple, powerful,
and expressive way to handle errors with:
bind() (Rust ?-like behavior)bail, ensure, and structured error propagationanyhow { } result builderbind() for early-return error propagation (Rust ?).context() and withContext() for rich error messagesbail() for immediate failureensure() / ensureNotNull() helpersResult to AnyhowResult
sourceSets {
commonMain.dependencies {
implementation("io.github.itsvks19:anyhowkt:<version>")
}
}dependencies {
implementation("io.github.itsvks19:anyhowkt:<version>")
}val result = anyhow {
val a = parseInt("10").bind()
val b = parseInt("20").bind()
a + b
}val value: Int = result.unwrap()Rust:
let value = compute()?;Kotlin (AnyhowKt):
val value = compute().bind()This works inside anyhow { } blocks.
val result = anyhow {
val file = readFile("config.json")
.anyhowResult { "file not found" }
.bind() // Early return on readFile failure
parseConfig(file)
.anyhow()
.bind()
}.context("Failed to load application config")Error output becomes:
Failed to load application config
Caused by: file not found
...
val result = anyhow {
if (user == null) {
bail("User not found")
}
user.name
}anyhow {
ensure(x > 0) { "x must be positive" }
ensureNotNull(user) { "user is required" }
ensureEquals(a, b) { "values must match" }
}val kResult: Result<Int> = runCatching { riskyCall() }
val result: AnyhowResult<Int> = kResult.anyhow()This library internally uses arrow-kt.
If you are using an IntelliJ IDEA or any other IDE from JetBrains, we strongly recommend installing the Arrow plug-in. The plug-in helps fix common problems, especially in the realm of typed errors and suggests more idiomatic alternatives when available.
Rust (anyhow) |
Kotlin (AnyhowKt) |
|---|---|
anyhow::Result<T> |
AnyhowResult<T> |
? |
.bind() |
bail!("msg") |
bail("msg") |
.context("msg") |
.context("msg") |
ensure!(cond) |
ensure(cond) |
MIT License.
PRs and feature requests are welcome! If you'd like to help add:
feel free to contribute ✨