-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
We want to filter all exception - that is ones that are uncaught as well as ones that are imperatively sent through CrashReportService That requires attaching filter to out Thread.defaultExceptionHandler chain - extract filter into service, use it from crash report service - implement default exception handler handling, init/reinit as needed - concrete types for the handlers and public uninstall/install for testability
- Loading branch information
Showing
6 changed files
with
162 additions
and
30 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/ThrowableFilterService.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/**************************************************************************************** | ||
* Copyright (c) 2024 voczi <[email protected]> | ||
* Copyright (c) 2024 Mike Hardy <[email protected]> * | ||
* * | ||
* This program is free software; you can redistribute it and/or modify it under * | ||
* the terms of the GNU General Public License as published by the Free Software * | ||
* Foundation; either version 3 of the License, or (at your option) any later * | ||
* version. * | ||
* * | ||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY * | ||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * | ||
* PARTICULAR PURPOSE. See the GNU General Public License for more details. * | ||
* * | ||
* You should have received a copy of the GNU General Public License along with * | ||
* this program. If not, see <http://www.gnu.org/licenses/>. * | ||
****************************************************************************************/ | ||
package com.ichi2.anki.servicelayer | ||
|
||
import androidx.annotation.VisibleForTesting | ||
import net.ankiweb.rsdroid.exceptions.BackendSyncException.BackendSyncServerMessageException | ||
import timber.log.Timber | ||
|
||
object ThrowableFilterService { | ||
|
||
@FunctionalInterface | ||
fun interface FilteringExceptionHandler : Thread.UncaughtExceptionHandler | ||
|
||
@VisibleForTesting | ||
var originalUncaughtExceptionHandler: Thread.UncaughtExceptionHandler? = null | ||
|
||
var uncaughtExceptionHandler = FilteringExceptionHandler { | ||
thread: Thread?, throwable: Throwable -> | ||
if (thread == null) { | ||
Timber.w("unexpected: thread was null") | ||
return@FilteringExceptionHandler | ||
} | ||
if (shouldDiscardThrowable(throwable)) { | ||
Timber.i("discarding throwable") | ||
return@FilteringExceptionHandler | ||
} | ||
originalUncaughtExceptionHandler?.uncaughtException(thread, throwable) | ||
} | ||
|
||
fun initialize() { | ||
Timber.i("initialize()") | ||
installDefaultExceptionHandler() | ||
} | ||
|
||
/** | ||
* We want to filter any exceptions with PII, then chain to other handlers | ||
*/ | ||
@Synchronized | ||
@VisibleForTesting | ||
fun installDefaultExceptionHandler() { | ||
originalUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler() | ||
Timber.d("Chaining to uncaughtExceptionHandler (%s)", originalUncaughtExceptionHandler) | ||
Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler) | ||
} | ||
|
||
/** | ||
* Reset the default exception handler | ||
*/ | ||
@Synchronized | ||
@VisibleForTesting | ||
fun unInstallDefaultExceptionHandler() { | ||
Thread.setDefaultUncaughtExceptionHandler(originalUncaughtExceptionHandler) | ||
originalUncaughtExceptionHandler = null | ||
} | ||
|
||
/** | ||
* Re-Initialize the throwable filter | ||
*/ | ||
@Synchronized | ||
fun reInitialize() { | ||
// send any pending async hits, re-chain default exception handlers and re-init | ||
Timber.i("reInitialize()") | ||
unInstallDefaultExceptionHandler() | ||
initialize() | ||
} | ||
|
||
fun shouldDiscardThrowable(t: Throwable): Boolean { | ||
return !t.safeFromPII() | ||
} | ||
|
||
/** | ||
* Checks if the [Throwable] is safe from Personally Identifiable Information (PII) | ||
* @return `false` if the [Throwable] contains PII, otherwise `true` | ||
*/ | ||
fun Throwable.safeFromPII(): Boolean { | ||
if (this.containsPIINonRecursive()) return false | ||
return this.cause?.safeFromPII() != false | ||
} | ||
|
||
private fun Throwable.containsPIINonRecursive(): Boolean { | ||
// BackendSyncServerMessage may contain PII and we do not want this leaked to ACRA. | ||
// Related: https://github.com/ankidroid/Anki-Android/issues/17392 | ||
// and also https://github.com/ankitects/anki/commit/ba1f5f4 | ||
return this is BackendSyncServerMessageException | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters