-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
safeAsync #4253
Comments
Failures typically shouldn't be caught, they should be propagated upwards: they are supposed to encode failures, whereas expected erroneous things (like the user sending invalid input) are to be represented by returning a
If you don't want that to happen, then this can be reflected in how you create your coroutines. By default, coroutines in the same scope are considered to all be parts of the same computations; if one part fails, the rest of them should, too, because the complete computation can not be performed in any case anymore. If you want several coroutines in the same scope to fail independently, you need a SupervisorJob. Example: This code will crash every coroutine: runBlocking {
val scope = CoroutineScope(Dispatchers.Default)
val deferreds = List(10) { scope.async { if (it == 7) error(":(") else { delay(50); it } } }
println(deferreds.map { runCatching { it.await() } })
// [Failure(...), Failure(...), Failure(...), Failure(...) ...
} But this code will not: runBlocking {
val scope = CoroutineScope(Dispatchers.Default + SupervisorJob()) // Note the SupervisorJob!
val deferreds = List(10) { scope.async { if (it == 7) error(":(") else { delay(50); it } } }
println(deferreds.map { runCatching { it.await() } })
// [Success(0), Success(1), Success(2), Success(3), Success(4), Success(5), Success(6), Failure(java.lang.IllegalStateException: :(), Success(8), Success(9)]
} |
Thanks for the quick replay @dkhalanskyjb |
In the example, I'm showing what happens to
That's correct, but you don't want to fail if the deferred values fail, right?
Without profiling the code, making such conclusions is difficult. It may be just as efficient in your specific case, or it may be more efficient. Together with If you see any benchmark results demonstrating that |
Ok thanks a lot, I will test it and will let you know |
First of all, I am a huge fan of Kotlin Coroutines and I would like to contribute and add a small function that will be useful as I myself had to use it considering real world (real project requirements).
So I was using async and
awaitAll()
but the problem was that all my async tasks crashed if at least one of them crashed (throws an exception) and as far as I understand the only way is to use good old try-catch inside async block. That's fine, but since we use catch block now we need to considerCancellationException
and as you already guessed it it leads to bugs, cause in some cases someone may forget about cancelation and we have a bugSo here is my little function that uses try-catch, but also handles cancelation and can be safely used in list and not crash all tasks if one of them will be crashed:
and this is how it can be used:
Thanks in advance ✌️
The text was updated successfully, but these errors were encountered: