uber/RxDogTag

OnErrorNotImplementedException’s stacktrace isn’t cleared out when it should be

Closed this issue · 4 comments

Stacktrace:

2019-09-18 08:46:44.148 13557-13557/com.example.moshisample E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.moshisample, PID: 13557
    io.reactivex.exceptions.OnErrorNotImplementedException: Non-null value 'person' was null at $.person
    Caused by: com.squareup.moshi.JsonDataException: Non-null value 'person' was null at $.person
        at com.example.moshisample.MainActivity.button1Clicked(MainActivity.kt:54)
        at [[ ↑↑ Inferred subscribe point ↑↑ ]].(:0)
        at [[ ↓↓ Original trace ↓↓ ]].(:0)
        at com.example.moshisample.PersonJsonAdapter.fromJson(PersonJsonAdapter.kt:25)
        at com.example.moshisample.PersonJsonAdapter.fromJson(PersonJsonAdapter.kt:12)
        at com.squareup.moshi.JsonAdapter$2.fromJson(JsonAdapter.java:137)
        at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:45)
        at retrofit2.converter.moshi.MoshiResponseBodyConverter.convert(MoshiResponseBodyConverter.java:27)
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
        at retrofit2.OkHttpCall.execute(OkHttpCall.java:188)
        at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:45)
        at io.reactivex.Observable.subscribe(Observable.java:12267)
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
        at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
        at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
        at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

Android app build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    compileSdkVersion 29
    defaultConfig {
        applicationId "com.example.moshisample"
        minSdkVersion 23
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        targetCompatibility = "8"
        sourceCompatibility = "8"
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.squareup.retrofit2:retrofit:2.6.1'
    implementation 'com.squareup.retrofit2:converter-moshi:2.6.1'
    kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.8.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.6.1'
    implementation "io.reactivex.rxjava2:rxjava:2.2.8"
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
    implementation("com.uber.rxdogtag:rxdogtag:0.2.0")
}

MainActivity.kt

import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.squareup.moshi.JsonClass
import com.uber.rxdogtag.RxDogTag
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.OkHttpClient
import retrofit2.Response
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET


class MainActivity : AppCompatActivity() {

    lateinit var client: OkHttpClient
    lateinit var retrofit: Retrofit
    lateinit var service: MyService

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        RxDogTag.install()

        client = OkHttpClient.Builder()
            .build()

        retrofit = Retrofit.Builder()
            .baseUrl("http://www.mocky.io/v2/")
            .client(client)
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .addConverterFactory(MoshiConverterFactory.create())
            .build()

        service = retrofit.create(MyService::class.java)

        button1.setOnClickListener { button1Clicked() }

    }

    fun button1Clicked() {
        val call = service.getPersonExplicitNull()

        call.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({ t: Response<Person>? ->
                Toast.makeText(this@MainActivity, "Success", Toast.LENGTH_LONG).show()
            })
    }
}

interface MyService {
    //JSON:
    //    {
    //        "person": null
    //    }
    @GET("5d4da01d3300004b4433793d?mocky-delay=1000ms")
    fun getPersonExplicitNull(): Observable<Response<Person>>
}

@JsonClass(generateAdapter = true)
data class Person(
    val person: String = ""
)

This is different than the stacktrace you sent me in the kotlinlang slack. Can you paste that one + repro steps?

Here is the stacktrace... although I don't remember the repro steps which is why I tried to repro with the steps above. I do remember is that I just removed the onError block in my subscription to my retrofit observable.

2019-09-17 17:06:48.787 8147-8147/com.myapp.theapp.beta E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.myapp.theapp.beta, PID: 8147
    io.reactivex.exceptions.OnErrorNotImplementedException: The exception was not handled due to missing onError handler in the subscribe() method call. Further reading: https://github.com/ReactiveX/RxJava/wiki/Error-Handling | java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
        at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:704)
        at io.reactivex.internal.functions.Functions$OnErrorMissingConsumer.accept(Functions.java:701)
        at io.reactivex.internal.observers.LambdaObserver.onError(LambdaObserver.java:77)
        at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:67)
        at com.uber.rxdogtag.DogTagObserver.lambda$onNext$3$DogTagObserver(DogTagObserver.java:56)
        at com.uber.rxdogtag.-$$Lambda$DogTagObserver$Bul2aJuZ0nriT_735invreaJZFw.run(Unknown Source:4)
        at com.uber.rxdogtag.RxDogTag.guardedDelegateCall(RxDogTag.java:221)
        at com.uber.rxdogtag.DogTagObserver.onNext(DogTagObserver.java:56)
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:201)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255)
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        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:858)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
        at com.myapp.app.ProfileFragment$onViewCreated$1.onClick(ProfileFragment.kt:32)
        at [[ ↑↑ Inferred subscribe point ↑↑ ]].(:0)
        at [[ Originating callback: onNext ]].(:0)
        at [[ ↓↓ Original trace ↓↓ ]].(:0)
        at com.myapp.app.ProfileController.buildModels(ProfileFragment.kt:66)
        at com.airbnb.epoxy.EpoxyController$1.run(EpoxyController.java:268)
        at com.airbnb.epoxy.EpoxyController.requestModelBuild(EpoxyController.java:161)
        at com.myapp.app.ProfileFragment$onViewCreated$1$1.accept(ProfileFragment.kt:44)
        at com.myapp.app.ProfileFragment$onViewCreated$1$1.accept(ProfileFragment.kt:21)
        at io.reactivex.internal.observers.LambdaObserver.onNext(LambdaObserver.java:63)
        at com.uber.rxdogtag.DogTagObserver.lambda$onNext$3$DogTagObserver(DogTagObserver.java:56) 
        at com.uber.rxdogtag.-$$Lambda$DogTagObserver$Bul2aJuZ0nriT_735invreaJZFw.run(Unknown Source:4) 
        at com.uber.rxdogtag.RxDogTag.guardedDelegateCall(RxDogTag.java:221) 
        at com.uber.rxdogtag.DogTagObserver.onNext(DogTagObserver.java:56) 
        at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeOnObserver.onNext(ObservableSubscribeOn.java:58) 
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:201) 
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255) 
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124) 
        at android.os.Handler.handleCallback(Handler.java:873) 
        at android.os.Handler.dispatchMessage(Handler.java:99) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        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:858) 

Ok, without a repro case there's not much we can do. Feel free to post with repro steps if you see it again

Not sure what the actual issue is, I just reported it because you asked me to. Sorry about that @ZacSweers /shruggie