I'm having troubles using Coroutines in WorkManager. Here is the snippet of Worker class.
class ExampleWorker (context, workerParams) : CoroutineWorker(context, workerParams) { override suspend fun doWork(): Result = withContext(Dispatchers.IO) { //set foreground try { val result = provider.getMeResult() if(result.success) return@withContext Result.success else return@withContext Result.failure() } catch(e: Exception) { handleErrors() return@withContext Result.failure() } finally { //clean up tasks } }}Here is the getMeResult()
class Provider { private val resultState = State() private val exceptionHandler = CoroutineHandler { _, throwable -> //set result state to failed resultState.status = FAILED resultState.code = someErrorCode } private val runScope = CoroutineScope(Dispatchers.Default + exceptionHandler) private val jobsList = mutableListOf<Job>() suspend fun getMeResult(): State { val runJob = runScope.launch { someLongRunningTask() // spits result out to a channel, say itemsChannel } itemsChannel.consumeEach { //spawn a new coroutine to run the job concurrently val job = runScope.launch { somebackgroundTask() //Point A } jobsList.add(job) } //wait for all jobs to complete jobsList.joinAll() } //wait parent coroutine to complete runJob?.join() //once you reach here, looks everything has worked. Update run state to complete resultState.status = COMPLETE return resultState}Ideally, this works as expected and result status is returned. However, whenever an error is thrown from Point A, exception handler receives the error and getMeResult() returns COMPLETE value. Worker catch block is never invoked, no error code was set. How can I make this work so that the Worker gets failed status when an error occurs? Also, when I cancel runJob within exceptionHandler, it fires multiple CancellationException with root cause as the actual exception type, but that cause is always null if I catch it within the parent Coroutine.
Hope it makes sense.