Do not notify about a redaction whose target event is unknown

A redaction push whose redacts field the SDK could not map was reported as
an unknown error. The result processor only suppresses filtered-out and
redacted events; every other exception becomes a visible "you have N
notifications" fallback and also raises the battery optimisation banner.

So a deleted message could produce a notification about itself, which is
the opposite of what a redaction means, plus an unrelated banner.

The branch now throws EventFilteredOut, which the processor already drops
silently, and logs at warning level so the SDK gap still shows up in push
history.

Relates to https://github.com/element-hq/element-x-android/issues/5766
This commit is contained in:
hayaksi1
2026-08-09 04:08:55 +03:00
parent 044737a3a7
commit bc20e64c61
2 changed files with 10 additions and 3 deletions
@@ -284,8 +284,12 @@ class DefaultNotifiableEventResolver(
// Note: this case will be handled below
val redactedEventId = content.redactedEventId
if (redactedEventId == null) {
Timber.tag(loggerTag.value).d("redactedEventId is null.")
throw NotificationResolverException.UnknownError("redactedEventId is null")
// Treat it as filtered out rather than as an error: an unknown error is turned
// into a visible "you have N notifications" fallback plus a battery banner, so a
// redaction we cannot map would notify about a message that was just deleted.
// See https://github.com/element-hq/element-x-android/issues/5766
Timber.tag(loggerTag.value).w("Ignoring redaction notification with no redactedEventId.")
throw NotificationResolverException.EventFilteredOut
} else {
ResolvedPushEvent.Redaction(
sessionId = userId,
@@ -818,7 +818,7 @@ class DefaultNotifiableEventResolverTest : RobolectricTest() {
}
@Test
fun `resolve RoomRedaction with null redactedEventId should return null`() = runTest {
fun `resolve RoomRedaction with null redactedEventId is filtered out`() = runTest {
val sut = createDefaultNotifiableEventResolver(
notificationResult = Result.success(
mapOf(
@@ -834,6 +834,9 @@ class DefaultNotifiableEventResolverTest : RobolectricTest() {
val request = aPushRequest(A_SESSION_ID, A_ROOM_ID, AN_EVENT_ID, "firebase")
val result = sut.resolveEvents(A_SESSION_ID, listOf(request))
assertThat(result.getEvent(request)?.getOrNull()).isNull()
// Must be EventFilteredOut and not an error: the result processor renders a fallback
// notification for any other exception, which is the bug in #5766.
assertThat(result.getEvent(request)?.exceptionOrNull()).isEqualTo(NotificationResolverException.EventFilteredOut)
}
@Test