When using ```lifecycleScope.launchWhenStarted {``...
# android
k
When using
Copy code
lifecycleScope.launchWhenStarted {
how do you set an exception handler? There's no launchWhenStarted(errorHandler) version of this. try/catch ex:Exception seems like too broad a thing to do...
z
what kind of error handler are you trying to set that is less “broad” than a try/catch?
try/catch will handle any exceptions from the current coroutine, and you can use
withContext(CoroutineExceptionHandler { }) { …
to also handle exceptions from child coroutines
k
Trying to add a generic error handler mainly
E.g. dummy proof framework code.
Without resorting to catching ex:Exception which gets flagged by static analysis tools as being too broad (rightly so)
z
You should be able to suppress the warning from the static analysis tools.
Although I’d caution against automatically catching all exceptions as a “good thing” – exceptions are thrown for a reason. Catching them and dropping them automatically is likely to let issues go unnoticed, leave the app in a bad state, and be hard to debug.
1
k
Wouldn't be dropped... It's for catching and handling as an error display and logging... Just wish there were a launch(error handler) equivalent 🙂
z
if
launchWhenStarted
doesn’t take a
CoroutineContext
, you can just wrap the body in
withContext
like I mentioned above and it should do the same thing.
if you are calling just
launch
, you can certainly pass the
CoroutineExceptionHandler
directly to
launch
.
k
Yep... Doing the withContext thing..a bit cleaner than the try catch generic Exception 🙂
z
I’m not sure i agree it’s cleaner, but it does actually behave differently. Since CoroutineContext is propagated to children, using the CEH approach will handle child coroutines, whereas the try/catch approach will not. Also, the closest equivalent try/catch would be to catch
Throwable
, not just
Exception
.
👍 1
b
@Zach Klippenstein (he/him) [MOD] , iirc CEH can't be used with
withContext
block and only can be used in two ways: as part of scope or part of context passed into launch/async. So it should be known at first coroutine builder point
From the docs: In particular, all children coroutines (coroutines created in the context of another Job) delegate handling of their exceptions to their parent coroutine, which also delegates to the parent, and so on until the root, so the CoroutineExceptionHandler installed in their context is never used
👍 1
j
I usually do not throw exceptions anymore but return result objects. As Kotlin doesn't have any checked exceptions, it is impossible to know whether something might possibly fail down the line. Therefore I catch errors right at the source and wrap it in a result object. This makes the code cleaner, you don't forget things might throw an exception and because I have to unwrap it in a
when(result) { is Success -> {} is Error -> {} is Loading-> {} }
I am more eager to handle all cases in the UI as well.
z
My bad, didn’t realize the withContext limitation. Launching a new child with the handler inside the lifecycle-scoped coroutine should work though, right?
b
only with detaching Job I believe
I mean something like:
Copy code
coroutineScope { 
   launch(ceh) { 
   
   }
}
will not work either. By detaching I mean creating a new Job without parent:
Copy code
coroutineScope { 
   launch(Job() + ceh) { 
   
   }
}
should work, but it doesn't make much sense