Last active
October 19, 2020 19:20
-
-
Save diefferson/022fdfbdb913baa283b3a5b3df67d2de to your computer and use it in GitHub Desktop.
Async Catching
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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