Skip to content

Instantly share code, notes, and snippets.

@diefferson
Last active October 19, 2020 19:20
Show Gist options
  • Select an option

  • Save diefferson/022fdfbdb913baa283b3a5b3df67d2de to your computer and use it in GitHub Desktop.

Select an option

Save diefferson/022fdfbdb913baa283b3a5b3df67d2de to your computer and use it in GitHub Desktop.
Async Catching
package br.com.example.domain.interactor.base
import br.com.exmaple.domain.exception.ErrorHandler
import br.com.exmaple.domain.exception.MyCustomException
import kotlinx.coroutines.*
import org.koin.core.KoinComponent
import org.koin.core.inject
class ResultAsync<T> private constructor(
scope: CoroutineScope, val action: suspend () -> T) : KoinComponent {
var onSuccess: (T) -> Unit = {}
var onError: (e: MyCustomException) -> Unit = {}
var onStatusChange: (status: AsyncStatus) -> Unit = {}
private val errorHandler by inject<ErrorHandler>()
private val defaultDispatcher by inject<CoroutineDispatcher>()
companion object {
fun <T> with(scope: CoroutineScope, action: suspend () -> T): ResultAsync<T> {
return ResultAsync(scope, action)
}
}
init {
scope.launch(defaultDispatcher) {
withContext(Dispatchers.Main) { onStatusChange(AsyncStatus.RUNNING) }
runAction(success = {
withContext(Dispatchers.Main) {
onStatusChange(AsyncStatus.DONE)
onSuccess(it)
}
}, error = {
withContext(Dispatchers.Main) {
onStatusChange(AsyncStatus.ERROR)
onError(it)
}
})
}
}
private suspend fun runAction(success: suspend (T) -> Unit, error: suspend (MyCustomException) -> Unit) {
try {
val result = action()
success(result)
} catch (e: Exception) {
error(errorHandler.handler(e))
}
}
}
fun <T> ResultAsync<T>.onFailure(action: (exception: MyCustomException) -> Unit): ResultAsync<T> {
this.onError = action
return this
}
fun <T> ResultAsync<T>.onSuccess(action: (value: T) -> Unit): ResultAsync<T> {
this.onSuccess = action
return this
}
fun <T> ResultAsync<T>.onStatusChange(action: (AsyncStatus) -> Unit): ResultAsync<T> {
this.onStatusChange = action
return this
}
fun <T> CoroutineScope.asyncCatching(action: suspend () -> T): ResultAsync<T> {
return ResultAsync.with(this, action)
}
enum class AsyncStatus {
RUNNING,
DONE,
ERROR
}
package br.com.example.domain.interactor.base
import kotlinx.coroutines.CoroutineScope
/**
* Abstract class for a UseCase
*/
abstract class UseCase<Type, in Params> where Type : Any? {
abstract suspend fun run(params: Params): Type
operator fun invoke(scope: CoroutineScope, params: Params) = scope.asyncCatching {
run(params)
}
operator fun invoke(scope: CoroutineScope) = scope.asyncCatching {
run(None() as Params)
}
class None
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment