androidMain.com.copperleaf.ballast.firebase.FirebaseCrashlyticsInterceptor.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ballast-firebase-crashlytics Show documentation
Show all versions of ballast-firebase-crashlytics Show documentation
Automatically log exceptions thrown within Ballast ViewModels to Firebase Crashlytics
package com.copperleaf.ballast.firebase
import com.copperleaf.ballast.BallastInterceptor
import com.copperleaf.ballast.BallastLogger
import com.copperleaf.ballast.BallastNotification
import com.copperleaf.ballast.core.BallastException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.crashlytics.ktx.KeyValueBuilder
import com.google.firebase.crashlytics.ktx.setCustomKeys
import kotlin.reflect.KClass
class FirebaseCrashlyticsInterceptor(
private val crashlytics: FirebaseCrashlytics,
) : BallastInterceptor {
private object Keys {
const val ViewModelName = "ViewModelName"
const val InputType = "InputType"
const val EventType = "EventType"
const val SideJobKey = "SideJobKey"
const val ExceptionType = "ExceptionType"
}
override suspend fun onNotify(logger: BallastLogger, notification: BallastNotification) {
when (notification) {
is BallastNotification.InputAccepted -> {
if (!notification.input.isAnnotatedWith(FirebaseCrashlyticsIgnore::class)) {
crashlytics.setCustomKeys {
key(Keys.ViewModelName, notification.vm.name)
key(Keys.InputType, "${notification.vm.name}.${notification.input::class.java.simpleName}")
}
crashlytics.log("${notification.vm.name}.${notification.input}")
}
}
is BallastNotification.InputHandlerError -> {
onError(notification, "Input", notification.throwable, true) {
key(Keys.InputType, "${notification.vm.name}.${notification.input::class.java.simpleName}")
}
}
is BallastNotification.EventHandlerError -> {
onError(notification, "Event", notification.throwable, true) {
key(Keys.EventType, "${notification.vm.name}.${notification.event::class.java.simpleName}")
}
}
is BallastNotification.SideJobError -> {
onError(notification, "SideJob", notification.throwable, true) {
key(Keys.SideJobKey, "${notification.vm.name}.${notification.key}")
}
}
is BallastNotification.UnhandledError -> {
onError(notification, "Unknown", notification.throwable, false) {
}
}
else -> {}
}
}
private fun onError(
notification: BallastNotification,
type: String,
throwable: Throwable,
handled: Boolean,
extraKeys: KeyValueBuilder.() -> Unit,
) {
crashlytics.setCustomKeys {
key(Keys.ViewModelName, notification.vm.name)
key(Keys.ExceptionType, type)
extraKeys()
}
crashlytics.recordException(BallastException(throwable, handled, "[redacted]", emptyList()))
}
private fun T.isAnnotatedWith(annotationClass: KClass): Boolean {
return this::class.java.isAnnotationPresent(annotationClass.java)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy