https://kotlinlang.org logo
#coroutines
Title
# coroutines
a

aaverin

09/05/2018, 3:12 PM
Rewriting some RxJava to coroutines and replacing PublishSubject with BroadcastChannel. How can I send exception or error through BroadcastChannel?
s

Seri

09/05/2018, 3:17 PM
You could handle errors like any other event and send them as a typed object
p

Paul Woitaschek

09/05/2018, 3:24 PM
How do you send exceptions through a
PublishSubject
?
l

louiscad

09/05/2018, 4:08 PM
With Kotlin 1.3, you can send
SuccessOrFailure
through a channel. Otherwise, a sealed class or similar would be great
u

uli

09/05/2018, 6:26 PM
in Rx onError should really only be used if your steam fails, not for negative, but expected results. Maping this to channels, i would say instead of onError, you just throw in the produce. As in rx this should only be used exceptionally. Otherwise follow the suggestions above, regarding typed objects for errors.
👍 1
1
a

aaverin

09/06/2018, 11:00 AM
@uli that’s was my line of throught Problem is, I don’t have
produce
– I am wrapping a 3rd party library callback. So I have a channel, and callback, that will be invoked some time in the future, and might have error inside. If it happens, I need to inform my channel subscriber that something went wrong
I also would like to leave it on channel consumer to decide what to do with the error state
This is even more complexified by bad 3rd party library design – this callback is global, so I can’t just throw an exception there
@Paul Woitaschek with
onError()
?
@louiscad Hmm. Sounds like BroadcastChannel/Channel doesn’t really map that well to PublishSubject/Subject concept. So channel consumer would then have to throw an exception in case value happened to be a failure?
p

Paul Woitaschek

09/06/2018, 11:07 AM
Then it terminates, that's usually not good
How does your code look like that you want to send exception?
a

aaverin

09/06/2018, 11:07 AM
I have a purchase callback coming from a library that can either be success or failure with a reason
My job is to hide this purchasing library completely from my end codebase
so my end application is supposed to get events, and react on them by showing, for example, error page
p

Paul Woitaschek

09/06/2018, 11:08 AM
Then mapping the event to an error code (i.e sealed class) would be the best way
I'm not sure this is built for that but you could close the channel using an exception
a

aaverin

09/06/2018, 11:09 AM
Looks like it’s the only way Still, purchasing error sounds like a bad thing to have, I wouldn’t mind Subject to unsubscribe
Well, now, how would you unit test this?
Copy code
sealed class PurchaseEvent {
    object Success : PurchaseEvent()
    data class Error(val reason: String) : PurchaseEvent()
}

@Singleton
internal class ChanneledPurchaseHandler @Inject constructor() {

    val purchaseHandler = object : PurchaseHandler {
        override fun onPurchaseSuccess() {
            launch { channel.send(PurchaseEvent.Success) }
        }

        override fun onPurchaseFailure(errorCode: Int, errorMessage: String?) {
            launch { channel.send(PurchaseEvent.Error("$errorCode $errorMessage")) }
        }
    }

    val channel = BroadcastChannel<PurchaseEvent>(1)
}
ok, I was able to change channel
send
to
sendBlocking
and test was easy
l

louiscad

09/06/2018, 3:51 PM
@aaverin You can wrap the channel calls to throw when attempting to receive an error. I do something like this in my company's library BleGattCoroutines
4 Views