All Projects → icerockdev → moko-errors

icerockdev / moko-errors

Licence: Apache-2.0 License
Automated exceptions handler for mobile (android & ios) Kotlin Multiplatform development.

Programming Languages

kotlin
9241 projects

Projects that are alternatives of or similar to moko-errors

moko-network
Network components with codegeneration of rest api for mobile (android & ios) Kotlin Multiplatform development
Stars: ✭ 107 (+137.78%)
Mutual labels:  coroutines, kotlin-native, kotlin-multiplatform, moko
moko-web3
Ethereum Web3 implementation for mobile (android & ios) Kotlin Multiplatform development
Stars: ✭ 32 (-28.89%)
Mutual labels:  kotlin-native, kotlin-multiplatform, moko
moko-geo
Geolocation access for mobile (android & ios) Kotlin Multiplatform development
Stars: ✭ 41 (-8.89%)
Mutual labels:  kotlin-native, kotlin-multiplatform, moko
kotlin-multiplatform-example
A Kotlin multiplatform example app that targets Android, ReactJS, iOS, JavaFx, and Spring Boot
Stars: ✭ 115 (+155.56%)
Mutual labels:  error-handling, kotlin-native, kotlin-multiplatform
moko-maps
Control your map from common code for mobile (android & ios) Kotlin Multiplatform development
Stars: ✭ 47 (+4.44%)
Mutual labels:  kotlin-native, kotlin-multiplatform, moko
moko-graphics
Graphics primitives for mobile (android & ios) Kotlin Multiplatform development
Stars: ✭ 11 (-75.56%)
Mutual labels:  kotlin-native, kotlin-multiplatform, moko
koru
Simple coroutine wrappers for Kotlin Native. Generated from annotations. Compatible with RxSwift, Combine etc.
Stars: ✭ 141 (+213.33%)
Mutual labels:  coroutines, kotlin-native, kotlin-multiplatform
Splitties
A collection of hand-crafted extensions for your Kotlin projects.
Stars: ✭ 1,945 (+4222.22%)
Mutual labels:  coroutines, kotlin-native, kotlin-multiplatform
MultiplatformPlayground
Kotlin Multiplatform project in Jetpack Compose & SwiftUI with shared ViewModel layer and File upload
Stars: ✭ 72 (+60%)
Mutual labels:  kotlin-native, kotlin-multiplatform, moko
KotlinMultiplatformAndoridParcelize
Use the Parcelize Annotation of the Kotlin Android Extensions in Kotin Multiplatform projects
Stars: ✭ 16 (-64.44%)
Mutual labels:  kotlin-native, kotlin-multiplatform
libs.kmp.icerock.dev
Kotlin Multiplatform libraries list with info auto-fetch
Stars: ✭ 178 (+295.56%)
Mutual labels:  kotlin-native, kotlin-multiplatform
kgql
GraphQL Document wrapper generator for Kotlin Multiplatform Project and Android
Stars: ✭ 54 (+20%)
Mutual labels:  kotlin-native, kotlin-multiplatform
island-time
A Kotlin Multiplatform library for working with dates and times
Stars: ✭ 69 (+53.33%)
Mutual labels:  kotlin-native, kotlin-multiplatform
devtools-library
Multiplatform, pluggable, extensible, and dynamic config library which supports YAML and JSON as a source.
Stars: ✭ 15 (-66.67%)
Mutual labels:  kotlin-native, kotlin-multiplatform
mqtt
Kotlin cross-platform, coroutine based, reflectionless MQTT 3.1.1 & 5.0 client & server
Stars: ✭ 31 (-31.11%)
Mutual labels:  coroutines, kotlin-native
SQLiter
Minimal multiplatform sqlite library
Stars: ✭ 120 (+166.67%)
Mutual labels:  kotlin-native, kotlin-multiplatform
storyblok-mp-SDK
Storyblok Kotlin Multiplatform SDK (Android, JVM, JS, iOS, ...)
Stars: ✭ 16 (-64.44%)
Mutual labels:  kotlin-native, kotlin-multiplatform
thelema-engine
Thelema - 3D graphics engine, written in Kotlin. Based on sources of libGDX.
Stars: ✭ 51 (+13.33%)
Mutual labels:  kotlin-native, kotlin-multiplatform
Lastik
Kotlin Multiplatform + Jetpack Compose pet project, based on www.last.fm/api (in development)
Stars: ✭ 37 (-17.78%)
Mutual labels:  coroutines, kotlin-multiplatform
chip-8
Jetpack Compose and SwiftUI based Kotlin Multiplatform fork of https://github.com/cbeust/chip-8 (Chip-8 Emulator)
Stars: ✭ 36 (-20%)
Mutual labels:  kotlin-native, kotlin-multiplatform

moko-errors

GitHub license Download kotlin-version

Mobile Kotlin errors

This is a Kotlin MultiPlatform library that provides automatic exception handling and automatic error displaying to a screen.

Table of Contents

Features

  • ExceptionHandler implements safe code execution and automatic exception display using ErrorPresenter.
  • ExceptionMappersStorage singleton object, storage that stores a set of exception converters to error classes required for ErrorPresenter objects.
  • ErrorPresenter classes implements a strategy for displaying exceptions in a user-friendly form on the platforms. Converts the exception class to an error object to display. There are several ErrorPresenter implementations: AlertErrorPresenter - displays errors text in alert dialogs, ToastErrorPresenter - displays errors text in toasts for Android and in alert dialog for iOS, SnackBarErrorPresenter - displays errors text in snackbar for Android and in alert dialog for iOS, SelectorErrorPresenter - for selecting error presenter by some custom condition.

Requirements

  • Gradle version 6.8+
  • Android API 16+
  • iOS version 11.0+

Installation

root build.gradle

allprojects {
    repositories {
        mavenCentral()
    }
}

project build.gradle

dependencies {
    commonMainApi("dev.icerock.moko:errors:0.6.0")
}

Usage

ExceptionMappersStorage

Registration of simple custom exceptions mapper in the singleton storage:

ExceptionMappersStorage
    .register<IllegalArgumentException, StringDesc> {   // Will map all IllegalArgumentException instances to StringDesc
        "Illegal argument was passed!".desc()
    }
    .register<HttpException, Int> {                     // Will map all HttpException instances to Int
        it.code
    }

Registration of custom exception mapper with condition:

ExceptionMappersStorage.condition<StringDesc>(              // Registers exception mapper Throwable -> StringDesc
    condition = { it is CustomException && it.code == 10 }, // Condition that maps Throwable -> Boolean
    mapper = { "Custom error happened!".desc() }            // Mapper for Throwable that matches to the condition
)

For every error type you should to set fallback (default) value using method setFallbackValue
(except StringDesc class which already has default value).

ExceptionMappersStorage
    .setFallbackValue<Int>(520) // Sets for Int error type default value as 520

// Creates new mapper that for any unregistered exception will return the fallback value - 520
val throwableToIntMapper: (Throwable) -> Int = ExceptionMappersStorage.throwableMapper()

Using factory method throwableMapper you can create exception mappers automaticlly:

val throwableToIntMapper: (Throwable) -> Int = ExceptionMappersStorage.throwableMapper()

If a default value is not found when creating a mapper using factory method throwableMapper, an exception will be thrown FallbackValueNotFoundException

The registration can be done in the form of an endless chain:

ExceptionMappersStorage
    .condition<StringDesc>(
        condition = { it is CustomException && it.code == 10 },
        mapper = { "Custom error happened!".desc() }
    )
    .register<IllegalArgumentException, StringDesc> {
        "Illegal argument was passed!".desc()
    }
    .register<HttpException, Int> {
        it.code
    }
    .setFallbackValue<Int>(520)

ExceptionHandler

E.g. declare ExceptionHandler property in some ViewModel class:

class SimpleViewModel(
    val exceptionHandler: ExceptionHandler
) : ViewModel() {
    // ...
}

Bind ExceptionHandler in the platform code.

On Android in an Activity of Fragment:

viewModel.exceptionHandler.bind(
    lifecycleOwner = this,
    activity = this
)

On iOS in a ViewController:

viewModel.exceptionHandler.bind(viewController: self)

Creating instances of ExceptionHandler class which uses (Throwable) -> StringDesc mappers:

ExceptionHandler<StringDesc>(
    errorPresenter = errorsPresenterInstance,                    // Concrete ErrorPresenter implementation
    exceptionMapper = ExceptionMappersStorage.throwableMapper(), // Create mapper (Throwable) -> StringDesc from ExceptionMappersStorage
    onCatch = {                                                  // Optional global catcher
        println("Got exception: $it")                            // E.g. here we can log all exceptions that are handled by ExceptionHandler
    }
)

And use it to safe requests in ViewModel:

fun onSendRequest() {
    viewModelScope.launch {
        exceptionHandler.handle {
            serverRequest()     // Some dangerous code that can throw an exception
        }.finally {             // Optional finally block
            // Some code        
        }.execute()             // Starts code execution in `handle` lambda
    }
}

Also you can add some custom catch handlers for ExceptionHandler that work as a catch in the try/catch operator:

fun onSendRequest() {
    viewModelScope.launch {
        exceptionHandler.handle {
            serverRequest()
        }.catch<IllegalArgumentException> {     // Specifying exception class
            // Some custom handler code
            false                               // true - cancels ErrorPresenter; false - allows execution of ErrorsPresenter
        }.execute()                             // Starts code execution in `handle` lambda
    }
}

ErrorPresenter

There are ErrorPresenter interface implementations:

  • AlertErrorPresenter - displays errors text in alert dialogs;
  • ToastErrorPresenter - displays errors text in toasts for Android (for iOS shows alert dialog);
  • SnackBarErrorPresenter - displays errors text in snackbar for Android (for iOS shows alert dialog);
  • SelectorErrorPresenter - for selecting error presenter by some custom condition.

You need to pass some ErrorPresenter to ErrorHandler instance. E.g. creation of error presenters in common code:

val alertErrorPresenter = AlertErrorPresenter(
    alertTitle = "Error".desc(),
    positiveButtonText = "OK".desc()
)
val toastErrorPresenter = ToastErrorPresenter(
    duration = ToastDuration.LONG
)

SelectorErrorPresenter - special presenter that select some error presenter by custom condition lambda which should return some ErrorPresenter to be used for showing errors:

val selectorErrorPresenter = SelectorErrorPresenter { throwable ->
    when (throwable) {
        is CustomException -> alertErrorPresenter
        else -> toastErrorPresenter
    }
}

And pass some ErrorPresenter to ErrorHandler:

val exceptionHandler = ExceptionHandler(
    errorPresenter = selectorErrorPresenter,
    exceptionMapper = ExceptionMappersStorage.throwableMapper()
)

Samples

Please see more examples in the sample directory.

Set Up Locally

Contributing

All development (both new features and bug fixes) is performed in the develop branch. This way master always contains the sources of the most recently released version. Please send PRs with bug fixes to the develop branch. Documentation fixes in the markdown files are an exception to this rule. They are updated directly in master.

The develop branch is pushed to master on release.

For more details on contributing please see the contributing guide.

License

Copyright 2020 IceRock MAG Inc.

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].