Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import com.technogym.android.absolute.strength.coreDomainModuleName

plugins {
alias(libs.plugins.cvshowcase.application)
alias(libs.plugins.cvshowcase.flavors)
Expand All @@ -14,6 +16,7 @@ dependencies{
//App dependencies
implementation(project(":$coreModuleName:$designSystemModuleName"))
implementation(project(":$coreModuleName:$commonModuleName"))
implementation(project(":$coreModuleName:$coreDomainModuleName"))
implementation(project(":$coreModuleName:$coreDataModuleName"))
//Feature module dependencies
implementation(project(":$featureModuleName:$profileModuleName"))
Expand Down
17 changes: 11 additions & 6 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# Preserve line number information for debugging stack traces sent to Crashlytics.
-keepattributes SourceFile,LineNumberTable

# Hide the original source file name in stack traces.
-renamesourcefileattribute SourceFile

#Firebase
-keep class com.crashlytics.** { *; }
-dontwarn com.crashlytics.**
-keep public class * extends java.lang.Exception


# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.alexfin90.cvshowcase.logging

import timber.log.Timber

object CvShowcaseDebugTree : Timber.DebugTree() {

override fun createStackElementTag(element: StackTraceElement): String {
return "${super.createStackElementTag(element)}:${element.lineNumber}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.alexfin90.cvshowcase.logging

import timber.log.Timber

fun plantTimberTree() {
Timber.plant(CvShowcaseDebugTree)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import android.app.Application
import android.os.StrictMode
import android.os.StrictMode.ThreadPolicy.Builder
import android.os.StrictMode.VmPolicy
import com.alexfin90.cvshowcase.logging.plantTimberTree
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class CvApplication : Application() {
override fun onCreate() {
super.onCreate()
plantTimberTree()
setStrictModePolicy()
//TODO Timber
}
}

Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/alexfin90/cvshowcase/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ import com.alexfin90.designsystem.theme.CvshowcaseTheme
import com.alexfin90.detailexperience.DetailExperienceScreen
import com.alexfin90.experience.ExperienceScreen
import dagger.hilt.android.AndroidEntryPoint
import timber.log.Timber

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Timber.d("onCreate")
enableEdgeToEdge()
setContent {
CvshowcaseTheme {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.alexfin90.cvshowcase.logging

import android.util.Log
import com.alexfin90.domain.exception.NonFatalException
import com.google.firebase.crashlytics.FirebaseCrashlytics
import timber.log.Timber

object CvShowcaseReleaseTree : Timber.Tree() {

private const val TAG = "CvShowcase"
private const val CRASHLYTICS_KEY_PRIORITY = "priority"
private const val CRASHLYTICS_KEY_TAG = "tag"
private const val CRASHLYTICS_KEY_MESSAGE = "message"
private const val CRASHLYTICS_KEY_ERROR_CODE = "code"

override fun isLoggable(tag: String?, priority: Int): Boolean {
return priority >= Log.WARN
}

override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
val logTag = tag ?: TAG

// Always output to Logcat for WARN/ERROR/ASSERT
Log.println(priority, logTag, message)

// Send ONLY NonFatalException to Crashlytics
if (t is NonFatalException) {
recordToCrashlytics(priority, logTag, message, t)
}
}

private fun recordToCrashlytics(
priority: Int,
tag: String,
message: String,
t: NonFatalException,
) {
try {
val crashlytics = FirebaseCrashlytics.getInstance()
crashlytics.setCustomKey(CRASHLYTICS_KEY_PRIORITY, priorityLabel(priority))
crashlytics.setCustomKey(CRASHLYTICS_KEY_TAG, tag)
crashlytics.setCustomKey(CRASHLYTICS_KEY_MESSAGE, message)
crashlytics.setCustomKey(CRASHLYTICS_KEY_ERROR_CODE, t.code)
crashlytics.log("$tag: $message")
crashlytics.recordException(t)
} catch (_: IllegalStateException) {
// Crashlytics not initialized (e.g., mock flavor)
}
}

private fun priorityLabel(priority: Int): String = when (priority) {
Log.ERROR -> "ERROR"
Log.WARN -> "WARN"
Log.ASSERT -> "ASSERT"
else -> "UNKNOWN"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.alexfin90.cvshowcase.logging

import timber.log.Timber

fun plantTimberTree() {
Timber.plant(CvShowcaseReleaseTree)
}
2 changes: 2 additions & 0 deletions core/domain/consumer-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Optional: Keep custom exceptions.
-keep class com.alexfin90.domain.exception.** { *; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.alexfin90.domain.exception

open class NonFatalException(
open val code: String,
override val message: String,
) : Exception(message) {
companion object {
const val GENERIC_NON_FATAL_ERROR = "GENERIC_NON_FATAL_ERROR"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import timber.log.Timber
import javax.inject.Inject

@Stable
Expand All @@ -21,6 +22,7 @@ class DetailExperienceViewModel @Inject constructor(
val uiState = _uiState.asStateFlow()

init {
Timber.d("init")
val title: String = savedStateHandle.toRoute<Route.DetailExperience>().title
_uiState.update {
it.copy(title = title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.update
import timber.log.Timber
import javax.inject.Inject


Expand All @@ -33,10 +34,10 @@ class ExperienceViewModel @Inject constructor(

companion object {
private const val DEBOUNCE_TIME = 500L
private val TAG = ExperienceViewModel::javaClass.name
}

init {
Timber.d("init")
observeCvUseCase()
.onStart { _uiState.update { it.copy(isLoading = true) } }
.onEach { cv ->
Expand Down
Loading