Reputation: 1682
I am trying to subscribe to a SingleSource
, I have implemented both onSuccess
And onError
of subscribe
method, here is my code:
disposable.add(repository
.getUser1()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
toast(it)
}, {
toast(it.message ?: "Error")
}))
The Problem is When an exception occur in repository it does't being caught in onError
Here is my repository implementation:
class Repository(private val sp: SharedPreferences) {
// It crashes
fun getUser1(): Single<String> = generateUser(name, "Hello")
// it doesn't crash
fun getUser2(): Single<String> = Single.fromCallable { name }.flatMap { generateUser(it, "Hello") }
private var name: String
get() = sp.getString("user", null) ?: throw NoNameException()
set(value) = sp.edit().putString("user", value).apply()
private fun generateUser(name: String, message: String): Single<String> = Single.just("$message $name")
}
And here is the crash Log:
09-24 10:13:40.930 6934-6934/com.mosius.samplerxtest E/AndroidRuntime: FATAL EXCEPTION: main Process: com.mosius.samplerxtest, PID: 6934 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:503) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826) Caused by: com.mosius.samplerxtest.NoNameException: No Name Supplied at com.mosius.samplerxtest.Repository.getName(Repository.kt:17) at com.mosius.samplerxtest.Repository.getUser1(Repository.kt:10) at com.mosius.samplerxtest.MainActivity$onCreate$1.onClick(MainActivity.kt:24) at android.view.View.performClick(View.java:6597) at android.view.View.performClickInternal(View.java:6574) at android.view.View.access$3100(View.java:778) at android.view.View$PerformClick.run(View.java:25881) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6649) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)
What's the different between these two implementation?
Upvotes: 0
Views: 930
Reputation: 1682
In the getUser1()
method, SingleSource
has not been created yet, so it is out of Rx control to handle the exception.
In the Second one the name is being fetched in Rx scope therefore it could handle the exception
Upvotes: 1