Kotlin coroutines handle error and implementation

后端 未结 2 966
太阳男子
太阳男子 2020-12-14 23:44

Using coroutines for the first time. Need help.

Here is my flow:

Presenter wants to login so calls Repository Interface. Repository implements RepositoryInte

2条回答
  •  -上瘾入骨i
    2020-12-15 00:12

    EDIT:

    I am trying this solution in my new app and i released that if an error occurs in launchSafe method and try to retry request, launcSafe() method does not work correctly. So i changed the logic like this and problem is fixed.

    fun CoroutineScope.launchSafe(
        onError: (Throwable) -> Unit = {},
        onSuccess: suspend () -> Unit
    ) {
       launch {
            try {
                onSuccess()
            } catch (e: Exception) {
                onError(e)
            }
        }
    }
    

    OLD ANSWER:

    I think a lot about this topic and came with a solution. I think this solution cleaner and easy to handle exceptions. First of all when use write code like

    fun getNames() = launch { }  
    

    You are returning job instance to ui i think this is not correct. Ui should not have reference to job instance. I tried below solution it's working good for me. But i want to discuss if any side effect can occur. Appreciate to see your comments.

    fun main() {
    
    
        Presenter().getNames()
    
        Thread.sleep(1000000)
    
    }
    
    
    class Presenter(private val repository: Repository = Repository()) : CoroutineScope {
    
        private val job = Job()
    
        override val coroutineContext: CoroutineContext
            get() = job + Dispatchers.Default // Can be Dispatchers.Main in Android
    
        fun getNames() = launchSafe(::handleLoginError) {
            println(repository.getNames())
        }
        
    
        private fun handleLoginError(throwable: Throwable) {
            println(throwable)
        }
    
        fun detach() = this.cancel()
    
    }
    
    class Repository {
    
        suspend fun getNames() = suspendCancellableCoroutine> {
            val timer = Timer()
    
            it.invokeOnCancellation {
                timer.cancel()
            }
    
            timer.schedule(timerTask {
                it.resumeWithException(IllegalArgumentException())
                //it.resume(listOf("a", "b", "c", "d"))
            }, 500)
        }
    }
    
    
    fun CoroutineScope.launchSafe(
        onError: (Throwable) -> Unit = {},
        onSuccess: suspend () -> Unit
    ) {
        val handler = CoroutineExceptionHandler { _, throwable ->
            onError(throwable)
        }
    
        launch(handler) {
            onSuccess()
        }
    }
    

提交回复
热议问题