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.