4

From What is the difference between launch/join and async/await in Kotlin coroutines:

launch is used to fire and forget coroutine. It is like starting a new thread. If the code inside the launch terminates with exception, then it is treated like uncaught exception in a thread -- usually printed to stderr in backend JVM applications and crashes Android applications. join is used to wait for completion of the launched coroutine and it does not propagate its exception. However, a crashed child coroutine cancels its parent with the corresponding exception, too.

If join doesn't propagate the exception, is there a way to wait for completion of a Job which does?

E.g. suppose that some library method returns a Job because it assumed its users wouldn't want to propagate exceptions, but it turns out there is a user who does want it; can this user get it without modifying the library?

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487

1 Answers1

0

Please use join + invokeOnCompletion method

Code will be like this:

suspend fun awaitError(job: Job): Throwable? {
    val errorAwaiter = CompletableDeferred<Throwable?>();        

    job.invokeOnCompletion { errorAwaiter.complete(it) }

    require(job.IsActive) {
         "Job was completed for too fast, probably error is missed"
    }

    val errorRaised = errorAwaiter.await();

    return when(errorRaised) {
         is CancellationException -> null
         else -> errorRaised
    }
}

Please note, that code will raise error for the fast jobs, so please be carefully. Possible it is better just to return null in this case (in my example).

Manushin Igor
  • 3,398
  • 1
  • 26
  • 40