Updated on 2026-08-14
This commit is contained in:
parent
9e948f7703
commit
147625bda1
40 changed files with 254 additions and 131 deletions
|
|
@ -1,20 +1,20 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import com.tangem.common.json.MoshiJsonConverter
|
||||
import com.tangem.core.analytics.api.ErrorEventLogger
|
||||
import com.tangem.core.analytics.api.ExceptionLogger
|
||||
import com.tangem.core.analytics.api.EventLogger
|
||||
import timber.log.Timber
|
||||
|
||||
class AnalyticsEventsLogger(
|
||||
private val name: String,
|
||||
private val jsonConverter: MoshiJsonConverter,
|
||||
) : EventLogger, ErrorEventLogger {
|
||||
) : EventLogger, ExceptionLogger {
|
||||
|
||||
override fun logEvent(event: String, params: Map<String, String>) {
|
||||
Timber.d(jsonConverter.prettyPrint(PrintEventModel(name, event, params)))
|
||||
}
|
||||
|
||||
override fun logErrorEvent(error: Throwable, params: Map<String, String>) {
|
||||
override fun logException(error: Throwable, params: Map<String, String>) {
|
||||
Timber.e(error, jsonConverter.prettyPrint(PrintEventModel(name, "error", params)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ internal sealed class Push(event: String) : AnalyticsEvent(
|
|||
category = "Push",
|
||||
event = event,
|
||||
params = emptyMap(),
|
||||
error = null,
|
||||
) {
|
||||
|
||||
data object PushNotificationOpened : Push(event = "Push Notification Opened")
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ sealed class Settings(
|
|||
category: String = "Settings",
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent(category, event, params, error) {
|
||||
) : AnalyticsEvent(category, event, params) {
|
||||
|
||||
class ScreenOpened : Settings(event = "Settings Screen Opened")
|
||||
class ButtonStartWalletConnectSession : Settings(event = "Button - Start Wallet Connect Session")
|
||||
|
|
@ -19,16 +18,14 @@ sealed class Settings(
|
|||
sealed class CardSettings(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
error: Throwable? = null,
|
||||
) : Settings("Settings / Card Settings", event, params, error) {
|
||||
) : Settings("Settings / Card Settings", event, params) {
|
||||
|
||||
class ButtonFactoryReset : CardSettings("Button - Factory Reset")
|
||||
class FactoryResetFinished(cardsCount: Int? = null, error: Throwable? = null) : CardSettings(
|
||||
class FactoryResetFinished(cardsCount: Int? = null) : CardSettings(
|
||||
event = "Factory Reset Finished",
|
||||
params = buildMap {
|
||||
cardsCount?.let { put("Cards Count", "$it") }
|
||||
},
|
||||
error = error,
|
||||
)
|
||||
|
||||
class FactoryResetCanceled(cardsCount: Int) : CardSettings(
|
||||
|
|
@ -44,10 +41,9 @@ sealed class Settings(
|
|||
params = mapOf("Type" to type.value),
|
||||
)
|
||||
|
||||
class SecurityModeChanged(mode: AnalyticsParam.SecurityMode, error: Throwable? = null) : CardSettings(
|
||||
class SecurityModeChanged(mode: AnalyticsParam.SecurityMode) : CardSettings(
|
||||
event = "Security Mode Changed",
|
||||
params = mapOf("Mode" to mode.value),
|
||||
error = error,
|
||||
)
|
||||
|
||||
class AccessCodeRecoveryChanged(status: AnalyticsParam.AccessCodeRecoveryStatus) : CardSettings(
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ import com.tangem.core.analytics.models.AnalyticsEvent
|
|||
sealed class SignIn(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent("Sign In", event, params, error) {
|
||||
) : AnalyticsEvent("Sign In", event, params) {
|
||||
|
||||
class ScreenOpened : SignIn(event = "Sign In Screen Opened")
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,7 @@ sealed class Token(
|
|||
category: String,
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent(category, event, params, error) {
|
||||
) : AnalyticsEvent(category, event, params) {
|
||||
|
||||
sealed class Receive(
|
||||
event: String,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ import com.tangem.tap.features.details.redux.walletconnect.WalletConnectAction.O
|
|||
internal sealed class WalletConnect(
|
||||
event: String,
|
||||
params: Map<String, String> = mapOf(),
|
||||
error: Throwable? = null,
|
||||
) : AnalyticsEvent("Wallet Connect", event, params, error) {
|
||||
) : AnalyticsEvent("Wallet Connect", event, params) {
|
||||
|
||||
class ScreenOpened : WalletConnect(event = "WC Screen Opened")
|
||||
class NewSessionInitiated(source: SourceType) : WalletConnect(
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
package com.tangem.tap.common.analytics.handlers.amplitude
|
||||
|
||||
import com.tangem.core.analytics.api.AnalyticsErrorHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
|
||||
class AmplitudeAnalyticsHandler(
|
||||
private val client: AmplitudeAnalyticsClient,
|
||||
) : AnalyticsHandler {
|
||||
) : AnalyticsHandler, AnalyticsErrorHandler {
|
||||
|
||||
override fun id(): String = ID
|
||||
|
||||
|
|
@ -13,6 +15,10 @@ class AmplitudeAnalyticsHandler(
|
|||
client.logEvent(eventId, params)
|
||||
}
|
||||
|
||||
override fun sendErrorEvent(event: AnalyticsEvent) {
|
||||
send(event.id, event.params)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val ID = "Amplitude"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
package com.tangem.tap.common.analytics.handlers.firebase
|
||||
|
||||
import com.google.firebase.analytics.FirebaseAnalytics
|
||||
import com.tangem.core.analytics.api.AnalyticsErrorHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsHandler
|
||||
import com.tangem.core.analytics.api.ErrorEventHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder
|
||||
import com.tangem.tap.common.analytics.converters.AnalyticsErrorConverter
|
||||
import com.tangem.tap.common.analytics.events.Shop
|
||||
|
||||
class FirebaseAnalyticsHandler(
|
||||
private val client: FirebaseAnalyticsClient,
|
||||
) : AnalyticsHandler, ErrorEventHandler {
|
||||
) : AnalyticsHandler, AnalyticsErrorHandler, AnalyticsExceptionHandler {
|
||||
|
||||
private val errorConverter = AnalyticsErrorConverter()
|
||||
|
||||
override fun id(): String = ID
|
||||
|
||||
|
|
@ -18,30 +20,17 @@ class FirebaseAnalyticsHandler(
|
|||
client.logEvent(eventId, params)
|
||||
}
|
||||
|
||||
override fun send(event: AnalyticsEvent) {
|
||||
val error = event.error
|
||||
when {
|
||||
error != null -> {
|
||||
val errorConverter = AnalyticsErrorConverter()
|
||||
if (!errorConverter.canBeHandled(error)) return
|
||||
override fun sendException(event: ExceptionAnalyticsEvent) {
|
||||
if (!errorConverter.canBeHandled(event.exception)) return
|
||||
|
||||
val errorParams = errorConverter.convert(error).toMutableMap()
|
||||
errorParams["Category"] = event.category
|
||||
errorParams["Event"] = event.event
|
||||
errorParams.putAll(event.params)
|
||||
send(error, errorParams)
|
||||
}
|
||||
event is Shop.Purchased -> {
|
||||
send(FirebaseAnalytics.Event.PURCHASE, event.params)
|
||||
}
|
||||
else -> {
|
||||
super.send(event)
|
||||
}
|
||||
}
|
||||
val errorParams = errorConverter.convert(event.exception).toMutableMap()
|
||||
errorParams.putAll(event.params)
|
||||
|
||||
client.logException(event.exception, event.params)
|
||||
}
|
||||
|
||||
override fun send(error: Throwable, params: Map<String, String>) {
|
||||
client.logErrorEvent(error, params)
|
||||
override fun sendErrorEvent(event: AnalyticsEvent) {
|
||||
send(event)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -4,14 +4,15 @@ import android.os.Bundle
|
|||
import androidx.core.os.bundleOf
|
||||
import com.google.firebase.analytics.ktx.analytics
|
||||
import com.google.firebase.crashlytics.ktx.crashlytics
|
||||
import com.google.firebase.crashlytics.recordException
|
||||
import com.google.firebase.ktx.Firebase
|
||||
import com.tangem.core.analytics.api.ErrorEventLogger
|
||||
import com.tangem.core.analytics.api.ExceptionLogger
|
||||
import com.tangem.core.analytics.api.EventLogger
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface FirebaseAnalyticsClient : EventLogger, ErrorEventLogger
|
||||
interface FirebaseAnalyticsClient : EventLogger, ExceptionLogger
|
||||
|
||||
internal class FirebaseClient : FirebaseAnalyticsClient {
|
||||
|
||||
|
|
@ -27,11 +28,12 @@ internal class FirebaseClient : FirebaseAnalyticsClient {
|
|||
)
|
||||
}
|
||||
|
||||
override fun logErrorEvent(error: Throwable, params: Map<String, String>) {
|
||||
eventConverter.convertEventParams(params)
|
||||
.forEach { fbCrashlytics.setCustomKey(it.key, it.value) }
|
||||
|
||||
fbCrashlytics.recordException(error)
|
||||
// TODO [REDACTED_TASK_KEY] fix recordException usages in the app
|
||||
override fun logException(error: Throwable, params: Map<String, String>) {
|
||||
fbCrashlytics.recordException(error) {
|
||||
eventConverter.convertEventParams(params)
|
||||
.forEach { key(it.key, it.value) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun Map<String, String>.toBundle(): Bundle = bundleOf(*this.toList().toTypedArray())
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ internal class FirebaseLogClient(
|
|||
logger.logEvent(event, params)
|
||||
}
|
||||
|
||||
override fun logErrorEvent(error: Throwable, params: Map<String, String>) {
|
||||
logger.logErrorEvent(error, params)
|
||||
override fun logException(error: Throwable, params: Map<String, String>) {
|
||||
logger.logException(error, params)
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,8 @@ import com.tangem.common.authentication.AuthenticationManager
|
|||
import com.tangem.common.card.FirmwareVersion
|
||||
import com.tangem.common.core.Config
|
||||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.crypto.bip39.Wordlist
|
||||
import com.tangem.data.card.sdk.CardSdkOwner
|
||||
import com.tangem.data.card.sdk.CardSdkProvider
|
||||
|
|
@ -33,7 +34,7 @@ import javax.inject.Singleton
|
|||
*/
|
||||
@Singleton
|
||||
internal class DefaultCardSdkProvider @Inject constructor(
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val cardSdkFeatureToggles: CardSdkFeatureToggles,
|
||||
) : CardSdkProvider, CardSdkOwner {
|
||||
|
|
@ -48,7 +49,12 @@ internal class DefaultCardSdkProvider @Inject constructor(
|
|||
override fun register(activity: FragmentActivity) = runBlocking(dispatchers.mainImmediate) {
|
||||
if (activity.isDestroyed || activity.isFinishing || activity.isChangingConfigurations) {
|
||||
val message = "Tangem SDK owner registration skipped: activity is destroyed or finishing"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(message))
|
||||
analyticsExceptionHandler.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = IllegalStateException(message),
|
||||
params = errorParams,
|
||||
),
|
||||
)
|
||||
Log.info { message }
|
||||
return@runBlocking
|
||||
}
|
||||
|
|
@ -66,14 +72,24 @@ internal class DefaultCardSdkProvider @Inject constructor(
|
|||
|
||||
private fun tryToRegisterWithForegroundActivity(): TangemSdk = runBlocking(dispatchers.mainImmediate) {
|
||||
val warning = "Tangem SDK holder is null, trying to recreate it with foreground activity"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(warning))
|
||||
analyticsExceptionHandler.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = IllegalStateException(warning),
|
||||
params = errorParams,
|
||||
),
|
||||
)
|
||||
Log.warning { warning }
|
||||
|
||||
val activity = foregroundActivityObserver.foregroundActivity
|
||||
|
||||
if (activity == null) {
|
||||
val error = "Tangem SDK holder is null and foreground activity is null"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(error))
|
||||
analyticsExceptionHandler.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = IllegalStateException(error),
|
||||
params = errorParams,
|
||||
),
|
||||
)
|
||||
Log.error { error }
|
||||
error(error)
|
||||
}
|
||||
|
|
@ -84,7 +100,12 @@ internal class DefaultCardSdkProvider @Inject constructor(
|
|||
|
||||
if (sdk == null) {
|
||||
val error = "Tangem SDK is null after re-registering with foreground activity"
|
||||
analyticsEventHandler.send(TangemSdkWarningEvent(error))
|
||||
analyticsExceptionHandler.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = IllegalStateException(error),
|
||||
params = errorParams,
|
||||
),
|
||||
)
|
||||
Log.error { error }
|
||||
error(error)
|
||||
}
|
||||
|
|
@ -174,5 +195,10 @@ internal class DefaultCardSdkProvider @Inject constructor(
|
|||
),
|
||||
),
|
||||
)
|
||||
|
||||
val errorParams = mapOf(
|
||||
"Category" to "Tangem SDK",
|
||||
"Event" to "Warning",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
package com.tangem.tap.data
|
||||
|
||||
import com.tangem.core.analytics.models.AnalyticsEvent
|
||||
|
||||
internal class TangemSdkWarningEvent(message: String) : AnalyticsEvent(
|
||||
category = "Tangem SDK",
|
||||
event = "Warning",
|
||||
error = IllegalStateException(message),
|
||||
)
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.di.routing
|
||||
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.tap.routing.ProxyAppRouter
|
||||
import com.tangem.tap.routing.configurator.AppRouterConfig
|
||||
import com.tangem.tap.routing.configurator.MutableAppRouterConfig
|
||||
|
|
@ -17,8 +18,15 @@ internal object AppRouterModule {
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideAppRouter(config: AppRouterConfig, dispatchers: CoroutineDispatcherProvider): AppRouter =
|
||||
ProxyAppRouter(config, dispatchers)
|
||||
fun provideAppRouter(
|
||||
config: AppRouterConfig,
|
||||
dispatchers: CoroutineDispatcherProvider,
|
||||
analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
): AppRouter = ProxyAppRouter(
|
||||
config = config,
|
||||
dispatchers = dispatchers,
|
||||
analyticsExceptionHandler = analyticsExceptionHandler,
|
||||
)
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import com.tangem.common.routing.AppRoute
|
|||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.AnalyticsParam
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.domain.card.ScanCardException
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.redux.StateDialog
|
||||
|
|
@ -34,7 +35,12 @@ internal object UseCaseScanProcessor {
|
|||
ifLeft = {
|
||||
val error = scanCardExceptionConverter.convertBack(it)
|
||||
|
||||
Analytics.send(Basic.ScanError(error))
|
||||
Analytics.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = error,
|
||||
params = mapOf("Event" to "Scan"),
|
||||
),
|
||||
)
|
||||
CompletionResult.Failure(error)
|
||||
},
|
||||
ifRight = { CompletionResult.Success(it) },
|
||||
|
|
@ -97,7 +103,12 @@ internal object UseCaseScanProcessor {
|
|||
-> {
|
||||
val error = scanCardExceptionConverter.convertBack(exception)
|
||||
|
||||
Analytics.send(Basic.ScanError(error))
|
||||
Analytics.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = error,
|
||||
params = mapOf("Event" to "Scan"),
|
||||
),
|
||||
)
|
||||
onFailure(error)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import com.tangem.common.extensions.ByteArrayKey
|
|||
import com.tangem.common.services.secure.SecureStorage
|
||||
import com.tangem.common.usersCode.UserCodeRepository
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.Basic
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.core.res.getStringSafe
|
||||
import com.tangem.crypto.bip39.DefaultMnemonic
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
|
|
@ -224,7 +224,12 @@ internal class DefaultTangemSdkManager(
|
|||
private fun sendScanResultsToAnalytics(result: CompletionResult<ScanResponse>) {
|
||||
if (result is CompletionResult.Failure) {
|
||||
(result.error as? TangemSdkError)?.let { error ->
|
||||
Analytics.send(Basic.ScanError(error))
|
||||
Analytics.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = error,
|
||||
params = mapOf("Event" to "Scan"),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,9 @@ import androidx.compose.runtime.Stable
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.domain.common.util.cardTypesResolver
|
||||
|
|
@ -30,6 +32,8 @@ internal class SecurityModeModel @Inject constructor(
|
|||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val tangemSdkManager: TangemSdkManager,
|
||||
private val cardSettingsInteractor: CardSettingsInteractor,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
) : Model() {
|
||||
|
||||
private val scannedScanResponse = cardSettingsInteractor.scannedScanResponse.value
|
||||
|
|
@ -85,14 +89,19 @@ internal class SecurityModeModel @Inject constructor(
|
|||
val paramValue = AnalyticsParam.SecurityMode.from(selectedOption)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
Analytics.send(Settings.CardSettings.SecurityModeChanged(paramValue))
|
||||
analyticsEventHandler.send(Settings.CardSettings.SecurityModeChanged(paramValue))
|
||||
|
||||
store.dispatchNavigationAction(AppRouter::pop)
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
val error = result.error
|
||||
if (error is TangemSdkError && error !is TangemSdkError.UserCancelled) {
|
||||
Analytics.send(Settings.CardSettings.SecurityModeChanged(paramValue, error))
|
||||
analyticsExceptionHandler.sendException(
|
||||
ExceptionAnalyticsEvent(
|
||||
exception = error,
|
||||
params = mapOf("Event" to "Security Mode Changed"),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package com.tangem.tap.features.onboarding.products.wallet.redux
|
||||
|
||||
import android.net.Uri
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.card.Card
|
||||
import com.tangem.common.core.TangemSdkError
|
||||
|
|
@ -12,6 +11,7 @@ import com.tangem.common.routing.AppRouter
|
|||
import com.tangem.common.services.Result
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.models.AnalyticsParam.ScreensSources
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.extensions.toWrappedList
|
||||
|
|
@ -454,8 +454,6 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
store.dispatchOnMain(BackupAction.AddBackupCard.Success(result.data))
|
||||
}
|
||||
is CompletionResult.Failure -> {
|
||||
val crashlytics = FirebaseCrashlytics.getInstance()
|
||||
|
||||
when (val error = result.error) {
|
||||
is TangemSdkError.CardVerificationFailed -> {
|
||||
Analytics.send(
|
||||
|
|
@ -492,7 +490,7 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
|
|||
GlobalAction.ShowDialog(BackupDialog.AttestationFailed),
|
||||
)
|
||||
}
|
||||
else -> crashlytics.recordException(error)
|
||||
else -> Analytics.sendException(ExceptionAnalyticsEvent(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
package com.tangem.tap.routing
|
||||
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.core.analytics.api.AnalyticsExceptionHandler
|
||||
import com.tangem.core.analytics.models.ExceptionAnalyticsEvent
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.tap.routing.configurator.AppRouterConfig
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
|
|
@ -15,6 +16,7 @@ import kotlin.reflect.KClass
|
|||
internal class ProxyAppRouter(
|
||||
private val config: AppRouterConfig,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val analyticsExceptionHandler: AnalyticsExceptionHandler,
|
||||
) : AppRouter {
|
||||
|
||||
private val routerScope: CoroutineScope
|
||||
|
|
@ -76,7 +78,7 @@ internal class ProxyAppRouter(
|
|||
|
||||
override fun defaultCompletionHandler(isSuccess: Boolean, errorMessage: String) {
|
||||
if (!isSuccess) {
|
||||
FirebaseCrashlytics.getInstance().recordException(RuntimeException(errorMessage))
|
||||
analyticsExceptionHandler.sendException(ExceptionAnalyticsEvent(RuntimeException(errorMessage)))
|
||||
Timber.w(errorMessage)
|
||||
|
||||
with(receiver = config.snackbarHandler ?: return) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue