Adib Faramarzi
02/12/2022, 7:15 AMkotlin.
from kotlin.runCatching { ... }
?
I always have to import the second option if I want the shorter one.Chrimaeon
02/12/2022, 8:58 AMChrimaeon
02/12/2022, 8:58 AMAdib Faramarzi
02/12/2022, 10:15 AMrunCatching
and use it.
what it does is equivalent to writing full class names, as opposed to importing them and using their name.Chrimaeon
02/12/2022, 10:27 AMkotlin
is the package and you want to import a method. You can do
import kotlin.runCatching
Adib Faramarzi
02/12/2022, 11:18 AMrunCa
and then press tab, it inserts kotlin.runCatching
and not runCatching
(which will work file if it does place that).
no imports are needed.Chrimaeon
02/12/2022, 11:25 AMPaul Woitaschek
02/12/2022, 1:19 PMChrimaeon
02/12/2022, 1:41 PMrunCatching
is doing just wrapping the execution result in a Result
.Chrimaeon
02/12/2022, 1:42 PMAdib Faramarzi
02/12/2022, 2:35 PMPaul Woitaschek
02/12/2022, 2:43 PMrunCatching {
val name = parseAge(input)
uploadName(name)
}
You usually want to catch a very specific failure. And if now parseAge
is throwing an exception that gets wrapped in the result type as well. Ive seen a lot of bad code around the result typeAdam Powell
02/12/2022, 2:58 PMrunCatching
to get a result to pass to Continuation<T>.resumeWith(result)
it's probably not helping your designAdib Faramarzi
02/12/2022, 3:01 PMAdib Faramarzi
02/12/2022, 3:01 PMAdib Faramarzi
02/12/2022, 3:02 PMAdib Faramarzi
02/12/2022, 3:02 PMrunCatching {
getData()
}.fold({
data ->
updateState(data)
}, {
error ->
updateStateToFailed(error)
})
Adib Faramarzi
02/12/2022, 3:02 PMAdam Powell
02/12/2022, 3:03 PMAdam Powell
02/12/2022, 3:04 PMAdam Powell
02/12/2022, 3:07 PMPaul Woitaschek
02/12/2022, 3:08 PMUnknownFailure
Adam Powell
02/12/2022, 3:08 PMPaul Woitaschek
02/12/2022, 3:09 PMThe code pasted above will treat cancellation improperly in a suspend function outside of specific circumstances around itYep, that’s breaking structured concurrency and might bring you in really unexpected lands
Adam Powell
02/12/2022, 3:11 PMupdateStateToFailed
with any CancellationException that comes through, and you probably do want to rethrow it even then to continue handling cancellation properlyAdam Powell
02/12/2022, 3:13 PMResult<T>
as a common return type is an awkward design fit: https://www.artima.com/articles/the-trouble-with-checked-exceptionsAdam Powell
02/12/2022, 3:15 PMResult<T>
turns all exceptions into checked exceptions (the developer has to deal with them somehow at every level rather than letting them unwind the stack to a point that can make a semantically relevant decision about it) except without type safety of the exceptions themselves, and then you swallow a spider to catch the fly by adding railway operators to try to solve an ergonomic problem you createdPaul Woitaschek
02/12/2022, 3:16 PMAdib Faramarzi
02/12/2022, 9:44 PMrunCatching
.
the above example is not in a suspend function at all. It is inside a view model that is calling some suspend function, in its own scope. Doing a try-catch is almost exactly the same, but I think runCatching look a bit cleaner. If you do not want to catch all errors, you can always use the good old try-catch.
runCatching has some nice apis too. If you really don't care about the result of something and want a nullable value, you can use runCatching { ... }.getOrNull()
which has a more Kotlin-ish API (like Lists and ...).