Skip to content

Kotlin Multiplatform Error Handling. Catch and handle all errors. Avoid Crashes. Like Arrow but without the black magic. No boilerplate. No performance overhead. 90+ operators.

License

Notifications You must be signed in to change notification settings

respawn-app/ApiResult

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Dec 25, 2023
fa2bdda Β· Dec 25, 2023

History

43 Commits
Aug 29, 2023
Dec 25, 2023
Dec 11, 2023
Dec 12, 2023
Dec 25, 2023
Aug 29, 2023
Dec 25, 2023
Aug 26, 2023
Aug 26, 2023
Dec 11, 2023
Aug 26, 2023
Aug 30, 2023
Dec 12, 2023
Aug 26, 2023
Dec 25, 2023
Aug 26, 2023
Aug 26, 2023
Dec 12, 2023

Repository files navigation

ApiResult

CI License GitHub last commit Issues GitHub top language CodeFactor AndroidWeekly #556

badge badge badge badge badge badge badge badge badge badge badge

ApiResult is a Kotlin Multiplatform declarative error handling framework that is performant, easy to use and feature-rich.

ApiResult is Railway Programming and functional error handling on steroids.

Features

  • ApiResult is lightweight. The library tries to inline operators and reduce allocations where possible.
  • ApiResult offers 90+ operators covering most of possible use cases to turn your code from imperative and procedural to declarative and functional, which is more readable and extensible.
  • ApiResult defines a contract that you can use in your code. No one will be able to obtain the result of a computation without being forced to handle errors at compilation time.

Preview

// wrap a result of a computation and expose the result
class BillingRepository(private val api: RestApi) {

    suspend fun getSubscriptions() = ApiResult {
        api.getSubscriptions()
    } // -> ApiResult<List<Subscription>?>
}

// ----- 

// obtain and handle the result in the client code
val repo = BillingRepository( /* ... */)

fun onClickVerify() {
    val state: SubscriptionState = repo.getSubscriptions()
        .errorOnNull() // map nulls to error states with compile-time safety
        .recover<NotSignedInException, _> { emptyList() } // recover from some or all errors
        .require { securityRepository.isDeviceTrusted() } // conditionally fail the chain
        .mapValues(::SubscriptionModel) // map list items
        .filter { it.isPurchased } // filter values
        .mapError<NetworkException, _, _> { e -> BillingException(cause = e) } // map exceptions
        .then { validateSubscriptions(it) } // execute a computation and continue with its result, propagating errors
        .chain { updateGracePeriod(it) } // execute another computation, and if it fails, stop the chain
        .onError { subscriptionService.disconnect() } // executed on error
        .onEmpty { return SubscriptionState.NotSubscribed } // use non-local returns and short-circuit evaluation
        .fold(
            onSuccess = { SubscriptionState.Subscribed(it) },
            onError = { SubscriptionState.Error(it) },
        ) // unwrap the result to another value
    // ...
}

Quickstart

  • Documentation: Docs
  • KDoc: Javadoc
  • Latest version: Maven Central
[versions]
apiresult = "< Badge above πŸ‘†πŸ» >"

[dependencies]
apiresult = { module = "pro.respawn.apiresult:core", version.ref = "apiresult" } 

dependencies {
    // usually you will want to expose ApiResult types in your module APIs, so consider using api() for the dependency
    commonMainApi("pro.respawn.apiresult:core:<version>")
}

Ready to try? Start with reading the Quickstart Guide.

License

   Copyright 2022-2023 Respawn Team and contributors

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.