Since we are using Coroutines (1.3.5 used) we have a lot of crash : JobCancellationException - StandaloneCoroutine was cancelled.
I read a lot of thread about theses problems and I tried a lot of solution in production but crashes always occurs.
In all our viewmodels we are using the viewmodelscope so it's ok.
But in our data layer we need to launch a tracking events which are fire and forget task. In first step we used a GlobalScope.launch. I was thinking the CancelletationException was due to this global scope so I removed it and create an extension in the data layer with using a SupervisorJob and a CoroutineExceptionHandler:
private val appScope = CoroutineScope(Dispatchers.Default + SupervisorJob())
private val coroutineExceptionHandler by lazy { CoroutineExceptionHandler { _, throwable -> logw("Error occurred inside Coroutine.", throwable) } }
fun launchOnApp(block: suspend CoroutineScope.() -> Unit) {
appScope.launch(coroutineExceptionHandler) { block() }
}
But I always saw crashes with this code. Do I need to use cancelAndJoin method? Which strategy I can use with a clean archi and this kind of work please?
Thanks in advance
You can build an extension utility that catches the cancellation exception, and do what you want with it:
fun CoroutineScope.safeLaunch(block: suspend CoroutineScope.() -> Unit): Job {
return this.launch {
try {
block()
} catch (ce: CancellationException) {
// You can ignore or log this exception
} catch (e: Exception) {
// Here it's better to at least log the exception
Log.e("TAG","Coroutine error", e)
}
}
}
And you can use the extension with a coroutine scope of your choice, for example the global scope:
GlobalScope.safeLaunch{
// here goes my suspend functions and stuff
}
or any viewmodel scope:
myViewModel.viewModelScope.safeLaunch{
// here goes my suspend functions and stuff
}