Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Sentry scope usage #2024

Merged
merged 2 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@ object UnwrappingJsonListSerializer : JsonTransformingSerializer<String>(String.

override fun transformDeserialize(element: JsonElement): JsonElement {
return if (element is JsonArray) {
Sentry.withScope { scope ->
Sentry.captureMessage("Found an array of inReplyTo") { scope ->
scope.setExtra("inReplyToList", "ids: ${element.map { it }}")
Sentry.captureMessage("Found an array of inReplyTo")
}
element.first()
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,11 @@ interface Correspondent : Parcelable {

return@runCatching "$first$last".uppercase()
}.getOrElse { exception ->
Sentry.withScope { scope ->
Sentry.captureException(exception) { scope ->
scope.setExtra("email", email)
scope.setExtra("name size", name.count().toString())
scope.setExtra("name is blank", name.isBlank().toString())
scope.setExtra("characters not letters", name.filterNot(Char::isLetter))
Sentry.captureException(exception)
}

return@getOrElse ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,30 +165,31 @@ class Message : RealmObject {
runCatching {
_folders.single { _folders.count() == 1 || it.id != SEARCH_FOLDER_ID }
}.getOrElse {
Sentry.withScope { scope ->
scope.level = SentryLevel.ERROR
scope.setExtra("messageUid", uid)
scope.setExtra("email", AccountUtils.currentMailboxEmail.toString())
val sentryMessage = if (_folders.isEmpty()) {
"Message has 0 parent folders, it should not be possible"
} else {
scope.setExtra("folders", "${_folders.map { "role:[${it.role?.name}] (id:[${it.id}])" }}")
scope.setExtra("foldersCount", "${_folders.count()}")
val allFoldersAreSearch = _folders.all { it.id == SEARCH_FOLDER_ID }
val allFoldersAreTheSame = _folders.all { it.id == _folders.firstOrNull()?.id }
when {
allFoldersAreSearch -> {
"Message has multiple times the Search folder as parent, it should not be possible"
}
allFoldersAreTheSame -> {
"Message has multiple times the same parent folder, it should not be possible"
}
else -> {
"Message has multiple parent folders, it should not be possible"
}
val sentryMessage = if (_folders.isEmpty()) {
"Message has 0 parent folders, it should not be possible"
} else {
val allFoldersAreSearch = _folders.all { it.id == SEARCH_FOLDER_ID }
val allFoldersAreTheSame = _folders.all { it.id == _folders.firstOrNull()?.id }
when {
allFoldersAreSearch -> {
"Message has multiple times the Search folder as parent, it should not be possible"
}
allFoldersAreTheSame -> {
"Message has multiple times the same parent folder, it should not be possible"
}
else -> {
"Message has multiple parent folders, it should not be possible"
}
}
Sentry.captureMessage(sentryMessage)
}
Sentry.captureMessage(
sentryMessage,
SentryLevel.ERROR,
) { scope ->
scope.setExtra("messageUid", uid)
scope.setExtra("email", AccountUtils.currentMailboxEmail.toString())
scope.setExtra("folders", "${_folders.map { "role:[${it.role?.name}] (id:[${it.id}])" }}")
scope.setExtra("foldersCount", "${_folders.count()}")
}
_folders.first()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,17 @@ class Thread : RealmObject {
runCatching {
_folders.single()
}.getOrElse { exception ->
Sentry.withScope { scope ->
Sentry.captureMessage(
"Thread has several or 0 parent folders, it should not be possible",
SentryLevel.ERROR,
) { scope ->
scope.setTag("foldersId", _folders.joinToString { it.id })
scope.setTag("foldersCount", "${_folders.count()}")
scope.setExtra("foldersCount", "${_folders.count()}")
scope.setExtra("folders", "${_folders.map { "name:[${it.role?.name}] (id:[${it.id}])" }}")
scope.setExtra("threadUid", uid)
scope.setExtra("email", AccountUtils.currentMailboxEmail.toString())
scope.setExtra("exception message", exception.message.toString())
Sentry.captureMessage("Thread has several or 0 parent folders, it should not be possible", SentryLevel.ERROR)
}
_folders.first()
}
Expand Down Expand Up @@ -233,7 +235,7 @@ class Thread : RealmObject {
recipients.firstOrNull() to message.bimi

}.getOrElse { throwable ->
Sentry.withScope { scope ->
Sentry.captureException(throwable) { scope ->
scope.setExtra("thread.folder.role", folder.role?.name.toString())
scope.setExtra("thread.folder.id", folder.id)
scope.setExtra("thread.folderId", folderId)
Expand All @@ -242,7 +244,6 @@ class Thread : RealmObject {
scope.setExtra("thread.duplicates.count", "${duplicates.count()}")
scope.setExtra("thread.isFromSearch", "$isFromSearch")
scope.setExtra("thread.hasDrafts", "$hasDrafts")
Sentry.captureException(throwable)
}

null to null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,9 @@ class NotificationActionsReceiver : BroadcastReceiver() {
updateFolders(folders = listOf(message.folder, destinationFolder), mailbox, realm)
} else {
executeUndoAction(payload)
Sentry.withScope { scope ->
Sentry.captureException(first().getApiException()) { scope ->
scope.setTag("reason", "Notif action fail because of API call")
scope.setExtra("destination folder role", folderRole.name)
Sentry.captureException(first().getApiException())
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/com/infomaniak/mail/ui/BaseActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ open class BaseActivity : AppCompatActivity() {
if (AccountUtils.currentUser == null) runBlocking {
AccountUtils.requestCurrentUser()
if (AccountUtils.currentUser == null) {
Sentry.withScope { scope ->
Sentry.captureMessage("BaseActivity> the current user is null") { scope ->
scope.setExtra("has been fixed", "false")
Sentry.captureMessage("BaseActivity> the current user is null")
}
}
}
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/java/com/infomaniak/mail/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ import com.infomaniak.mail.utils.extensions.isUserAlreadySynchronized
import com.infomaniak.mail.workers.DraftsActionsWorker
import dagger.hilt.android.AndroidEntryPoint
import io.sentry.Sentry
import io.sentry.SentryLevel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
Expand Down Expand Up @@ -497,7 +496,7 @@ class MainActivity : BaseActivity() {
isVisible = true
playAnimation()
}
Sentry.captureMessage("Easter egg XMas has been triggered! Woohoo!", SentryLevel.INFO)
Sentry.captureMessage("Easter egg XMas has been triggered! Woohoo!")
trackEasterEggEvent("xmas${Date().year()}")
}
}
Expand Down
5 changes: 4 additions & 1 deletion app/src/main/java/com/infomaniak/mail/ui/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,10 @@ class MainViewModel @Inject constructor(

val filename = UUID.randomUUID().toString()
val emlAttachment = Attachment(response.body?.bytes(), filename, EML_CONTENT_TYPE)
Sentry.captureMessage("Message display problem reported", SentryLevel.ERROR) { scope ->
Sentry.captureMessage(
"Message display problem reported",
SentryLevel.ERROR,
) { scope ->
scope.addAttachment(emlAttachment)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,14 +723,13 @@ class ThreadListFragment : TwoPaneFragment(), SwipeRefreshLayout.OnRefreshListen

if (!areThereThreads && !isFilterEnabled && !isBooting && !isWaitingFirstThreads) {
val currentFolder = mainViewModel.currentFolder.value
Sentry.withScope { scope ->
Sentry.captureMessage(
"Should display threads is true but there are no threads to display",
SentryLevel.WARNING,
) { scope ->
scope.setExtra("cursor", "$currentFolderCursor")
scope.setExtra("folderRole", currentFolder?.role?.name.toString())
scope.setExtra("folderThreadsCount", "${currentFolder?.threads?.count()}")
Sentry.captureMessage(
"Should display threads is true but there are no threads to display",
SentryLevel.WARNING,
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,17 @@ class ThreadAdapter(
}

private fun isThemeTheSameForMessageUid(messageUid: String) = threadAdapterState.isThemeTheSameMap[messageUid] ?: run {
Sentry.withScope { scope ->
// TODO: Find the cause. The bug probably affects other parts of the code that do not crash
Sentry.captureMessage(
"Missing message uid inside isThemeTheSameMap",
SentryLevel.ERROR,
) { scope ->
val mapStringRepresentation = threadAdapterState.isThemeTheSameMap
.map { (key, value) -> "($key -> $value)" }
.joinToString(prefix = "[", postfix = "]")

scope.setExtra("isThemeTheSameMap", mapStringRepresentation)
scope.setExtra("looking for messageUid", messageUid)

// TODO: Find the cause. The bug probably affects other parts of the code that do not crash
Sentry.captureMessage("Missing message uid inside isThemeTheSameMap", SentryLevel.ERROR)
}

true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -630,15 +630,14 @@ class ThreadFragment : Fragment() {
} else {
val targetChild = binding.messagesList.getChildAt(indexToScroll)
if (targetChild == null) {
Sentry.withScope { scope ->
Sentry.captureMessage(
"Target child for scroll in ThreadFragment is null. Fallback to scrolling to bottom",
SentryLevel.ERROR,
) { scope ->
scope.setExtra("indexToScroll", indexToScroll.toString())
scope.setExtra("messageCount", threadAdapter.items.count().toString())
scope.setExtra("isExpandedMap", threadState.isExpandedMap.toString())
scope.setExtra("isLastMessageDraft", (threadAdapter.items.lastOrNull() as Message?)?.isDraft.toString())
Sentry.captureMessage(
"Target child for scroll in ThreadFragment is null. Fallback to scrolling to bottom",
SentryLevel.ERROR,
)
}
getBottomY()
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,7 @@ import com.infomaniak.mail.data.models.thread.Thread
import com.infomaniak.mail.di.IoDispatcher
import com.infomaniak.mail.ui.main.thread.ThreadAdapter.SuperCollapsedBlock
import com.infomaniak.mail.utils.*
import com.infomaniak.mail.utils.extensions.MergedContactDictionary
import com.infomaniak.mail.utils.extensions.appContext
import com.infomaniak.mail.utils.extensions.atLeastOneSucceeded
import com.infomaniak.mail.utils.extensions.getUids
import com.infomaniak.mail.utils.extensions.indexOfFirstOrNull
import com.infomaniak.mail.utils.extensions.*
import dagger.hilt.android.lifecycle.HiltViewModel
import io.realm.kotlin.MutableRealm
import io.realm.kotlin.query.RealmResults
Expand Down Expand Up @@ -381,11 +377,10 @@ class ThreadViewModel @Inject constructor(
if (apiResponse.isSuccess()) {
updateCalendarEvent(message, apiResponse.data!!)
} else {
Sentry.withScope { scope ->
Sentry.captureMessage("Failed loading calendar event") { scope ->
scope.setExtra("ics attachment mimeType", icsAttachment.mimeType)
scope.setExtra("ics attachment size", icsAttachment.size.toString())
scope.setExtra("error code", apiResponse.error?.code.toString())
Sentry.captureMessage("Failed loading calendar event")
}
}
}
Expand All @@ -395,13 +390,15 @@ class ThreadViewModel @Inject constructor(
localMessage?.let {
it.latestCalendarEventResponse = calendarEventResponse
} ?: run {
Sentry.withScope { scope ->
Sentry.captureMessage(
"Cannot find message by uid for fetched calendar event inside Realm",
SentryLevel.ERROR,
) { scope ->
scope.setExtra("message.uid", message.uid)
val hasUserStoredEvent = calendarEventResponse.hasAssociatedInfomaniakCalendarEvent()
scope.setExtra("event has userStoredEvent", hasUserStoredEvent.toString())
scope.setExtra("event is canceled", calendarEventResponse.isCanceled.toString())
scope.setExtra("event has attachmentEvent", calendarEventResponse.hasAttachmentEvent().toString())
Sentry.captureMessage("Cannot find message by uid for fetched calendar event inside Realm", SentryLevel.ERROR)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,11 +219,10 @@ class CalendarEventBannerView @JvmOverloads constructor(
private fun displayOrganizer(attendees: List<Attendee>) = with(binding) {
val organizers = attendees.filter(Attendee::isOrganizer)
if (organizers.count() > 1) {
Sentry.withScope { scope ->
Sentry.captureMessage("Found more than one organizer for an event") { scope ->
scope.setExtra("amount of organizer", organizers.count().toString())
scope.setExtra("have same email", organizers.all { it.email == organizers[0].email }.toString())
scope.setExtra("have same name", organizers.all { it.name == organizers[0].name }.toString())
Sentry.captureMessage("Found more than one organizer for an event")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ import com.infomaniak.mail.utils.extensions.bindAlertToViewLifecycle
import com.infomaniak.mail.utils.extensions.setSystemBarsColors
import dagger.hilt.android.AndroidEntryPoint
import io.sentry.Sentry
import io.sentry.SentryLevel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.launch
import java.util.Calendar
Expand Down Expand Up @@ -144,7 +143,7 @@ class AccountFragment : Fragment(), MailboxListFragment {

if ((month == Calendar.OCTOBER && day >= 26) || (month == Calendar.NOVEMBER && day <= 1)) {
binding.easterEggHalloween.isVisible = true
Sentry.captureMessage("Easter egg Halloween has been triggered! Woohoo!", SentryLevel.INFO)
Sentry.captureMessage("Easter egg Halloween has been triggered! Woohoo!")
trackEasterEggEvent("halloween${Date().year()}")
}
}
Expand Down
4 changes: 1 addition & 3 deletions app/src/main/java/com/infomaniak/mail/utils/ConfettiUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import com.infomaniak.mail.MatomoMail.trackEasterEggEvent
import com.infomaniak.mail.R
import com.infomaniak.mail.utils.extensions.isInPortrait
import io.sentry.Sentry
import io.sentry.SentryLevel
import com.infomaniak.lib.confetti.R as RConfetti

object ConfettiUtils {
Expand Down Expand Up @@ -62,9 +61,8 @@ object ConfettiUtils {
matomoValue: String,
) = with(container.context) {

Sentry.withScope { scope ->
Sentry.captureMessage("Easter egg Confetti has been triggered! Woohoo!") { scope ->
scope.setTag("from", matomoValue)
Sentry.captureMessage("Easter egg Confetti has been triggered! Woohoo!", SentryLevel.INFO)
}

trackEasterEggEvent("confetti$matomoValue")
Expand Down
24 changes: 12 additions & 12 deletions app/src/main/java/com/infomaniak/mail/utils/LocalStorageUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,10 @@ object LocalStorageUtils {

return@use getFileToUpload(context, uri, snackbarManager, attachmentsUploadDir, hashedFileName, inputStream)
} ?: run {
Sentry.withScope { scope ->
Sentry.captureMessage("failed to access uri") { scope ->
scope.setExtra("uri is absolute", uri.isAbsolute.toString())
scope.setExtra("uri is relative", uri.isRelative.toString())
scope.setExtra("uri is opaque", uri.isOpaque.toString())
Sentry.captureMessage("failed to access uri")
}
null
}
Expand All @@ -144,20 +143,21 @@ object LocalStorageUtils {
FileOutputStream(file).use(inputStream::copyTo)
true
}.getOrElse {
Sentry.withScope { scope ->

val exception = it.message
?.let { message -> AttachmentMissingFileException(message.replace(file.path, HIDDEN_FILE_NAME)) }
?: it
exception.stackTrace = it.stackTrace

Sentry.captureException(exception) { scope ->
scope.setExtra("uri", uri.toString().replace(file.path, HIDDEN_FILE_NAME))
val exception = it.message
?.let { message -> AttachmentMissingFileException(message.replace(file.path, HIDDEN_FILE_NAME)) }
?: it
}

exception.stackTrace = it.stackTrace
Sentry.captureException(exception)
val isNameLong = exception.message?.contains(NAME_TOO_LONG_EXCEPTION) == true
val snackbarMessageId = if (isNameLong) R.string.errorFileNameTooLong else RCore.string.errorFileNotFound

val isNameLong = exception.message?.contains(NAME_TOO_LONG_EXCEPTION) == true
val snackbarMessageId = if (isNameLong) R.string.errorFileNameTooLong else RCore.string.errorFileNotFound
snackbarManager.postValue(context.getString(snackbarMessageId))

snackbarManager.postValue(context.getString(snackbarMessageId))
}
false
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,12 @@ object MessageBodyUtils {
if (quotes.isEmpty() || quotes.all { it.isBlank() }) SplitBody(bodyContent) else SplitBody(content, bodyContent)
},
onTimeout = {
Sentry.withScope { scope ->
Sentry.captureMessage(
"Timeout reached while displaying a Message's body",
SentryLevel.WARNING,
) { scope ->
scope.setExtra("body size", "${bodyContent.toByteArray().size} bytes")
scope.setExtra("email", AccountUtils.currentMailboxEmail.toString())
Sentry.captureMessage("Timeout reached while displaying a Message's body", SentryLevel.WARNING)
}
},
)
Expand Down
Loading
Loading