I have a kotlin flow in which halfway an exception is thrown. No matter what I do, the exception is not caught.
The flow is like this: In the viewmodel I have value which needs to be reread from a database upon a change of date. I use a switchmap for this.
val branches:LiveData<List<SCBranch>> = currentDay.switchMap {
schooldataUseCases.getBranches(it)
.catch{
exception ->withContext(Dispatchers.Main) {
Timber.d("catching exception in switchmap")
uncaughtException.value = exception.message
}
}
.asLiveData
The useCase is as follows:
override fun getBranches(day:Day): Flow<List<SCBranch>> =
schooldataRepository.getBranchesForSchoolPeriodFlow(schoolPeriodManager.getSchoolPeriodFor(day.startTime))
The schoolPeriodManager selects a schoolPeriod for the requested date. If there is no schoolPeriod defined for the requested date it throws an exception. I want to catch that exception and inform the users they selected an invalid date through another liveData 'uncaughtexception'.
Alas, my app ends with an Fatal exception which is indeed the exception thrown by the schoolPeriodManager. So the catch block in the switchmap does not catch the exception.
I tried to add a CoroutineExceptionHandler to the flow like this:
val branches:LiveData<List<SCBranch>> = currentDay.switchMap {
schooldataUseCases.getBranches(it)
.asLiveData( exceptionHandler)
}
The exceptionHandler does not catch the exception either. The app still ends with the same Fatal Exception
How should I implement the catch block to catch the raised exception?
I had the same issue, mate.
In order to handle the catch, you must emit the value, for example:
But in your case, the value emitted on catch is not the same from the map, so maybe you need to create a wrapper class for this, such as a sealed class with content for success and Error on catch.
PS: The cast is needed on map because otherwise it will show an error that the liveData you're trying to use is the type of
BranchesState.Success
instead ofBranchesState