This commit addresses issue #265 where the NotificationReplyReceiver used an unbound CoroutineScope when handling asynchronous reply saves to the Room database. If the DAO operation hangs, the PendingResult.finish() method is never called, which could lead to an Application Not Responding (ANR) error. Changes made: - Wrapped the Room upsert operation inside a `withTimeout(5000L)` block within the IO coroutine in `NotificationReplyReceiver.kt`. - Ensures that if the operation exceeds 5 seconds, a TimeoutCancellationException is thrown and caught, allowing `pendingResult.finish()` to execute in the `finally` block. - Added a unit test in `NotificationReplyReceiverTest.kt` to verify that if the mock DAO hangs indefinitely, the PendingResult is still correctly finished after the timeout. Impact: - Prevents potential ANRs caused by stuck local DB transactions during inline notification replies.
This commit is contained in:
2 files changed
+39
-16
No files matched your search
@@ -252,6 +252,27 @@ class NotificationReplyReceiverTest {
|
||||
verify { mockPendingResult.finish() }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Room hang triggers timeout and finishes pending result`() {
|
||||
givenValidReply("session-abc", "Hello")
|
||||
|
||||
// Make upsert hang indefinitely
|
||||
coEvery { mockDao.upsert(any<ChatMessageEntity>()) } coAnswers {
|
||||
kotlinx.coroutines.delay(10000)
|
||||
}
|
||||
|
||||
receiver.onReceive(mockContext, mockIntent)
|
||||
|
||||
// Wait longer than the 5-second timeout, but less than the 10-second delay
|
||||
Thread.sleep(6000)
|
||||
|
||||
// Timeout should be caught in catch block and logged
|
||||
verify { android.util.Log.e("NotificationReply", any<String>(), any()) }
|
||||
|
||||
// Pending result must still finish after timeout
|
||||
verify { mockPendingResult.finish() }
|
||||
}
|
||||
|
||||
// ── Helpers ────────────────────────────────────────────────────────────
|
||||
|
||||
private fun givenValidReply(
|
||||
|
||||
Reference in new issue
Block a user