SharedFlow didn't cancel or throw exception with callbackFlow
See original GitHub issueThe exception didn’t throw to parent scope or cancel itself while using SharedFlow with callbackFlow. I tried to cancel sharedflow in case of failure. Here is my code snippet
fun adapt(call: Call<T>): SharedFlow<T> {
val scope = CoroutineScope(dispatcher)
return callbackFlow<T> {
call.enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
sendBlocking(response.body())
close()
}
override fun onFailure(call: Call<T>, t: Throwable) {
close(t)
}
})
awaitClose()
}.catch {
/**
*Here caught exception that threw in Failure case
* Try to cancel Job so SharedFlow can terminate but It didn't work However catching exception here won't crash my app
*/
scope.cancel()
}.shareIn(scope, SharingStarted.Lazily, 1)
}
I used it
runBlocking{
//this will get first output in case of success and then completed this coroutine
//But In case of Failure, this will always wait to get the first item and never completed
val result = adapt(someCall).first()
}
Here is another way tried to accomplish the same thing
fun adapt(call: Call<T>): SharedFlow<T> {
val scope = CoroutineScope(dispatcher)
return callbackFlow<T> {
call.enqueue(object : Callback<T> {
override fun onResponse(call: Call<T>, response: Response<T>) {
sendBlocking(response.body())
close()
}
override fun onFailure(call: Call<T>, t: Throwable) {
close(t)
}
})
awaitClose()
}.shareIn(scope, SharingStarted.Lazily, 1).catch {
/**
*This catch block never invoked in case of failure
* Try to cancel Job so sharedFlow can terminate its coroutine
*/
currentCoroutineContext().cancel()
}
}
I used this as previous but this time
runBlocking{
//this will get first output in case of success and then completed this coroutine
//But In case of Failure App crashes
val result = adapt(someCall).first()
}
sharedflow.collect|first()|take(1){} stays always in resume state I want to cancel it in case of failure.
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
Kotlin Flow: unsubscribe from SharedFlow when Fragment ...
After changing collection scope to viewModelScope , I was getting ChildCancelledException: Child of the scoped flow was cancelled exception ...
Read more >From RxJava to Kotlin Flow: Error Handling - ProAndroidDev
First of all, for our comparison, we'll create helper functions of Flow and Observable, which emit a value and then throw an exception....
Read more >Handle exceptions in callbackFlow with Kotlin | by Florent Blot
In order to propagate the exception, we have two choices: cancelling its coroutine's scope or closing its channel. Cancelling the scope can be...
Read more >Kotlin flows on Android - Android Developers
In coroutines, a flow is a type that can emit multiple values sequentially, as opposed to suspend functions that return only a single...
Read more >SharedFlow - Kotlin
This usually happens when the scope in which the coroutine is running is cancelled. A subscriber to a shared flow is always cancellable,...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
catch
onSharedFlow
is meaningless, sinceSharedFlow
never completes. I’ll add the corresponding Lint checks with warnings to explain it.Yes this is a nice trick but I wonder why
catch after shareIn didn’t catch anything and app crashes. And
Didn’t work.