Skip to content

Commit 39bebfe

Browse files
committed
Merge branch 'release/5.52.4'
2 parents b4e42b0 + f9c0371 commit 39bebfe

File tree

2 files changed

+35
-3
lines changed

2 files changed

+35
-3
lines changed

app/src/main/java/com/duckduckgo/app/global/AlertingUncaughtExceptionHandler.kt

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,28 +16,60 @@
1616

1717
package com.duckduckgo.app.global
1818

19+
import com.duckduckgo.app.browser.BuildConfig
1920
import com.duckduckgo.app.global.exception.UncaughtExceptionRepository
2021
import com.duckduckgo.app.global.exception.UncaughtExceptionSource
2122
import com.duckduckgo.app.statistics.store.OfflinePixelCountDataStore
2223
import kotlinx.coroutines.Dispatchers
2324
import kotlinx.coroutines.GlobalScope
2425
import kotlinx.coroutines.NonCancellable
2526
import kotlinx.coroutines.launch
27+
import java.io.InterruptedIOException
2628

2729
class AlertingUncaughtExceptionHandler(
2830
private val originalHandler: Thread.UncaughtExceptionHandler,
2931
private val offlinePixelCountDataStore: OfflinePixelCountDataStore,
3032
private val uncaughtExceptionRepository: UncaughtExceptionRepository
3133
) : Thread.UncaughtExceptionHandler {
3234

33-
override fun uncaughtException(t: Thread?, originalException: Throwable?) {
35+
override fun uncaughtException(thread: Thread?, originalException: Throwable?) {
3436

37+
if (shouldRecordExceptionAndCrashApp(originalException)) {
38+
recordExceptionAndAllowCrash(thread, originalException)
39+
return
40+
}
41+
42+
if (shouldCrashApp()) {
43+
originalHandler.uncaughtException(thread, originalException)
44+
}
45+
46+
}
47+
48+
/**
49+
* Some exceptions happen due to lifecycle issues, such as our sync service being forced to stop.
50+
* In such cases, we don't need to alert about the exception as they are exceptions essentially signalling that work was interrupted.
51+
* Examples of this would be if the internet was lost during the sync,
52+
* or when two or more sync operations are scheduled to run at the same time; one would run and the rest would be interrupted.
53+
*/
54+
private fun shouldRecordExceptionAndCrashApp(exception: Throwable?): Boolean {
55+
return when (exception) {
56+
is InterruptedException, is InterruptedIOException -> false
57+
else -> true
58+
}
59+
}
60+
61+
/**
62+
* If the exception is one we don't report on, we still want to see a crash when we're in DEBUG builds for safety we aren't ignoring important issues
63+
*/
64+
private fun shouldCrashApp(): Boolean = BuildConfig.DEBUG
65+
66+
private fun recordExceptionAndAllowCrash(thread: Thread?, originalException: Throwable?) {
3567
GlobalScope.launch(Dispatchers.IO + NonCancellable) {
3668
uncaughtExceptionRepository.recordUncaughtException(originalException, UncaughtExceptionSource.GLOBAL)
3769
offlinePixelCountDataStore.applicationCrashCount += 1
3870

3971
// wait until the exception has been fully processed before propagating exception
40-
originalHandler.uncaughtException(t, originalException)
72+
originalHandler.uncaughtException(thread, originalException)
4173
}
4274
}
4375
}

app/version/version.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
VERSION=5.52.3
1+
VERSION=5.52.4

0 commit comments

Comments
 (0)