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
17 changes: 12 additions & 5 deletions libs/logging/src/main/kotlin/com/getcode/utils/ErrorUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,7 @@ object ErrorUtils {
)
}

if (
BuildConfig.NOTIFY_ERRORS &&
ignoredErrors.none { it.isInstance(throwable) } &&
ignoredErrors.none { it.isInstance(throwableCause) }
) {
if (BuildConfig.NOTIFY_ERRORS && shouldReport(throwable, throwableCause)) {
val isNotifiable = when {
throwable is ConditionallyNotifiable -> throwable.isNotifiable
throwableCause is ConditionallyNotifiable -> throwableCause.isNotifiable
Expand All @@ -76,6 +72,17 @@ object ErrorUtils {
}
}

/**
* Whether [throwable] is worth handing to the reporters at all. [UnreportedError] marks an
* expected server result the caller already handles, so it stays in the log without opening a
* Bugsnag error group.
*/
internal fun shouldReport(throwable: Throwable, cause: Throwable): Boolean =
throwable !is UnreportedError &&
cause !is UnreportedError &&
ignoredErrors.none { it.isInstance(throwable) } &&
ignoredErrors.none { it.isInstance(cause) }

private fun isNetworkError(throwable: Throwable): Boolean =
throwable is TimeoutException ||
throwable.cause is TimeoutException ||
Expand Down
12 changes: 12 additions & 0 deletions libs/logging/src/main/kotlin/com/getcode/utils/UnreportedError.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.getcode.utils

/**
* Marker interface for errors that are an expected outcome rather than a fault — a server result
* the caller already handles and renders. [ErrorUtils] still logs these, so they stay in the trace
* attached to a real report, but it does not hand them to the reporters and they never open a
* Bugsnag error group.
*
* This is a third tier below [NotifiableError] (reported, WARNING, drives the Slack filter) and a
* plain [CodeServerError] (reported, INFO, recorded for reference).
*/
interface UnreportedError
37 changes: 37 additions & 0 deletions libs/logging/src/test/kotlin/com/getcode/utils/ErrorUtilsTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.getcode.utils

import java.net.UnknownHostException
import kotlin.test.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class ErrorUtilsTest {

private class Benign : Throwable("benign"), UnreportedError

private class Fault : Throwable("fault")

@Test
fun `a plain throwable is reported`() {
val error = Fault()
assertTrue(ErrorUtils.shouldReport(error, error))
}

@Test
fun `an UnreportedError is not reported`() {
val error = Benign()
assertFalse(ErrorUtils.shouldReport(error, error))
}

@Test
fun `an UnreportedError in the cause position is not reported`() {
assertFalse(ErrorUtils.shouldReport(Fault(), Benign()))
}

@Test
fun `ignored error types stay ignored`() {
val error = UnknownHostException("no dns")
assertFalse(ErrorUtils.shouldReport(error, error))
assertFalse(ErrorUtils.shouldReport(Fault(), error))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.flipcash.services.models.chat.BlobRejection
import com.getcode.solana.keys.Checksum
import com.getcode.utils.CodeServerError
import com.getcode.utils.NotifiableError
import com.getcode.utils.UnreportedError

sealed class LoginError(
override val message: String? = null,
Expand Down Expand Up @@ -374,7 +375,12 @@ sealed class GetMessagesError(
override val cause: Throwable? = null
): CodeServerError(message, cause) {
class Denied : GetMessagesError("Denied")
class NotFound : GetMessagesError("Not found")

/**
* The chat has no messages to return. Opening a conversation nobody has written in yet is a
* normal outcome, not a fault, so callers render an empty transcript and it is not reported.
*/
class NotFound : GetMessagesError("Not found"), UnreportedError
class Unrecognized : GetMessagesError("Unrecognized"), NotifiableError
data class Other(override val cause: Throwable? = null) : GetMessagesError(message = cause?.message, cause = cause), NotifiableError
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.flipcash.services.models

import com.getcode.utils.CodeServerError
import com.getcode.utils.UnreportedError
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertIs
Expand Down Expand Up @@ -147,6 +148,11 @@ class ErrorsTest {
assertIs<CodeServerError>(GetMessagesError.Other())
}

@Test
fun `GetMessagesError NotFound is not reported`() {
assertIs<UnreportedError>(GetMessagesError.NotFound())
}

// -- SendMessageError --

@Test
Expand Down
Loading