5

My target is to:

  • Log RxJava chain handled errors to Firebase Crashlytics
  • Get some sensible stacktraces (which points also to my code)
  • Make Firebase Crashlytics error grouping done right (not all issues grouped to one)

Current setup:

  • Add error listener to rxjava subscribe() and get throwable
  • To get better stacktraces use RxTracer lib
  • Log that throwable to Firebase Crashlytics using Crashlytics.logException(t)

Probem with this setup is that Firebase Crashlytics groups almost all errors under RxTracer TracingObserver.java – line 2 - com.halfhp.rxtracer.TracingObserver.

I can not find any way to add custom grouping has etc to Firebase Crashlytics

How are you guys reporting RxJava errors to Firebase Crashlytics?

devha
  • 3,307
  • 4
  • 28
  • 52
  • 1
    have a look at this post : https://rongi.github.io/kotlin-blog/rxjava/2017/09/25/breadcrumbs-rxjava-error-handling.html this would probably negate the requirement of the RxTracer library. – Mark Sep 02 '19 at 21:29

1 Answers1

0

Like I said in another answer, Crashlytics is grouping issues by the method and line where the root cause exception was created.

CompositeException mentioned in the blog post linked above is a nice tool to achieve two things: let your exception be the root cause while retaining the stack trace of the original exception.

Crashlytics.logException(CompositeException(throwable, RuntimeException()))

The above would group the Crashlytics issues by the place where you put that snippet, because the RuntimeException will be the root cause of the logged exception.

A function like this would probably be more useful:

import androidx.annotation.Keep
import com.crashlytics.android.Crashlytics
import io.reactivex.exceptions.CompositeException

class NonFatalException(message: String, cause: Throwable? = null) : RuntimeException(message, cause)

class BreadcrumbException : RuntimeException() {
    override fun getStackTrace() = super.getStackTrace()
            .dropWhile { it.className == "com.example.NonFatalExceptionKt" }
            .toTypedArray()
}

@Keep
fun logNonFatal(message: String, throwable: Throwable) {
    Crashlytics.logException(NonFatalException(message, CompositeException(throwable, BreadcrumbException())))
}

It can be used like this:

observable
    .doOnError { logNonFatal("Someone stuck in the thermosiphon", it) }
    .subscribe()

You'll get reports grouped by the line at which logNonFatal was invoked, rather than where root cause of it exception was created.

arekolek
  • 9,128
  • 3
  • 58
  • 79