Mattwalk
Mattwalk

Reputation: 139

How to handle exceptions in onError method of Observable?

My application crash when I logout from Firebase. I checked the logcat and it shows me the following stack trace.

 io.reactivex.exceptions.UndeliverableException: java.lang.Throwable: Permission denied
                                                   at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:349)
                                                   at io.reactivex.internal.operators.observable.ObservableCreate$CreateEmitter.onError(ObservableCreate.java:74)
                                                   at messenger.tarang.com.messenger.allusers.AllUsers$loadUsers$1$1.onCancelled(AllUsers.kt:78)
                                                   at com.google.android.gms.internal.zzecw.zza(Unknown Source)
                                                   at com.google.android.gms.internal.zzehy.zzbyc(Unknown Source)
                                                   at com.google.android.gms.internal.zzeig.run(Unknown Source)
                                                   at android.os.Handler.handleCallback(Handler.java:742)
                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                   at android.os.Looper.loop(Looper.java:154)
                                                   at android.app.ActivityThread.main(ActivityThread.java:5527)
                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
                                                Caused by: java.lang.Throwable: Permission denied
                                                   at messenger.tarang.com.messenger.allusers.AllUsers$loadUsers$1$1.onCancelled(AllUsers.kt:78) 
                                                   at com.google.android.gms.internal.zzecw.zza(Unknown Source) 
                                                   at com.google.android.gms.internal.zzehy.zzbyc(Unknown Source) 
                                                   at com.google.android.gms.internal.zzeig.run(Unknown Source) 
                                                   at android.os.Handler.handleCallback(Handler.java:742) 
                                                   at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                   at android.os.Looper.loop(Looper.java:154) 
                                                   at android.app.ActivityThread.main(ActivityThread.java:5527) 
                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739) 
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629) 

Here is the code where the problem arises.

Observable.create<DataSnapshot>{ emitter ->
        databaseReference
                ?.child("Users")
                ?.addChildEventListener(object : ChildEventListener{
                    override fun onCancelled(p0: DatabaseError?) {
                        if(!emitter.isDisposed){
                               emitter.onError(Throwable(p0.message))
                        }
                    }
                    override fun onChildMoved(p0: DataSnapshot?, p1: String?) {

                    }
                    override fun onChildChanged(p0: DataSnapshot?, p1: String?) {

                    }
                    override fun onChildAdded(p0: DataSnapshot?, p1: String?) {
                        if(!emitter.isDisposed)
                        emitter.onNext(p0!!)
                    }
                    override fun onChildRemoved(p0: DataSnapshot?) {

                    }
                })
    }.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(object : Observer<DataSnapshot>{
                override fun onComplete() {

                }

                override fun onNext(t: DataSnapshot) {
                        val userModel = t.getValue(UserModel::class.java)
                        userModel?.uid = t.key
                        userAdapter?.addData(userModel!!)
                }
                override fun onSubscribe(d: Disposable) {
                compositeDisposable?.add(d)
                }

                override fun onError(e: Throwable) {
                    e.printStackTrace()
                }
            })

Below is my Account Settings class where i am performing logout action.If i comment emitter.onError()in above code then i don't get any exceptions.

class AccountSettings internal constructor(): AppCompatActivity(), View.OnClickListener {
var toolbar : Toolbar ?= null
var toolbar_text : TextView ?= null
var logout_text : TextView ?= null
var firebaseAuth : FirebaseAuth ?= null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.account_settings)
    initialize()
}

override fun onStart() {
    super.onStart()
    logout_text?.setOnClickListener(this)
}

 fun initialize(){
     firebaseAuth = FirebaseAuth.getInstance()
    logout_text = findViewById(R.id.logout_text)
    toolbar = findViewById(R.id.toolbar)
    toolbar_text = toolbar?.findViewById(R.id.toolbar_text1)
    toolbar_text?.setText("Account Settings")
    toolbar_text?.visibility= View.VISIBLE
    setSupportActionBar(toolbar)
}

 fun logout() {
    try {
        firebaseAuth?.signOut()
        displayMessage("logout successfully")
        goToMainActivity()
    }
    catch(ex : Exception){
        ex.printStackTrace()
        displayMessage("you are not connected to Internet")
    }
}

 fun goToMainActivity() {
    var intents = Intent (this,CheckAuthenticate::class.java)
    intents.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
    startActivity(intents)
    finish()
}

 fun displayMessage(message: String) {
    Toast.makeText(this,message,Toast.LENGTH_SHORT).show()
}

override fun onClick(p0: View?) {
    when(p0?.id){
        R.id.logout_text ->{
            logout()
        }
    }
}

override fun onDestroy() {
    super.onDestroy()
}

}

What should i do to make it work? How should i properly handle this exception so that my application does not crash? Please help anyone...

Upvotes: 1

Views: 763

Answers (1)

Alexander Deych
Alexander Deych

Reputation: 446

You need to handle UndeliverableException. Add to your Application onCreate():

RxJavaPlugins.setErrorHandler(error -> {
        //Log error or just ignore it
    });

Upvotes: 2

Related Questions