commit 648d8bff8033e3a056f0ae2e4d64033d542246c1 parent 90107538e289ebacc74306fbc938769da767425a Author: Ben Dean-Kawamura <bdk@mozilla.com> Date: Mon, 20 Oct 2025 15:03:09 +0000 Bug 1994283 - Catch UniFFI InternalException, r=jonalmeida,skhan Catch UniFFI internal exceptions. These shouldn't be getting thrown, but we're seeing them in the wild (https://bugzilla.mozilla.org/show_bug.cgi?id=1989864). As a temporary measure, let's avoid crashing at least. I have some ideas for a long-term fix, but we won't be able to land those anytime soon. Record an error to Sentry when we do this. This way, when we get around to the long-term fix, we'll be able to test if the Sentry events go down. Refactored the error code a bit so that we can send a sentry error event from android components rather than Rust only. Differential Revision: https://phabricator.services.mozilla.com/D268912 Diffstat:
5 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/mobile/android/android-components/components/feature/fxsuggest/build.gradle b/mobile/android/android-components/components/feature/fxsuggest/build.gradle @@ -24,6 +24,7 @@ dependencies { implementation project(':components:concept-engine') implementation project(':components:feature-session') implementation project(':components:service-nimbus') + implementation project(':components:support-appservices') implementation project(':components:support-base') implementation project(':components:support-remotesettings') implementation project(':components:support-ktx') diff --git a/mobile/android/android-components/components/feature/fxsuggest/src/main/java/mozilla/components/feature/fxsuggest/FxSuggestStorage.kt b/mobile/android/android-components/components/feature/fxsuggest/src/main/java/mozilla/components/feature/fxsuggest/FxSuggestStorage.kt @@ -20,6 +20,8 @@ import mozilla.appservices.suggest.SuggestionQuery import mozilla.components.feature.fxsuggest.facts.emitSuggestionQueryCountFact import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.remotesettings.RemoteSettingsService +import mozilla.components.support.rusterrors.reportRustError +import mozilla.appservices.suggest.InternalException as UniffiInternalException /** * A coroutine-aware wrapper around the synchronous [SuggestStore] interface. @@ -122,6 +124,10 @@ class FxSuggestStorage( } catch (e: SuggestApiException) { logger.warn("Ignoring exception from `$name`", e) default + } catch (e: UniffiInternalException) { + Logger.error(e.toString()) + reportRustError("suggest-internal-error", e.toString()) + default } } diff --git a/mobile/android/android-components/components/support/appservices/src/main/java/mozilla/components/support/rusterrors/RustErrors.kt b/mobile/android/android-components/components/support/appservices/src/main/java/mozilla/components/support/rusterrors/RustErrors.kt @@ -18,7 +18,8 @@ import mozilla.components.concept.base.crash.RustCrashReport * errors like network errors, will be counted with Glean. */ public fun initializeRustErrors(crashReporter: CrashReporting) { - setApplicationErrorReporter(AndroidComponentsErrorReportor(crashReporter)) + ErrorReporter.crashReporter = crashReporter + setApplicationErrorReporter(ErrorReporter) } internal class AppServicesErrorReport( @@ -26,14 +27,24 @@ internal class AppServicesErrorReport( override val message: String, ) : Exception(typeName), RustCrashReport -private class AndroidComponentsErrorReportor( - val crashReporter: CrashReporting, -) : ApplicationErrorReporter { +/** + * Report an error from a Rust component to sentry + * + * Normally these error reports come from Rust, but this function provides a way to do it from + * Kotlin code. + */ +fun reportRustError(typeName: String, message: String) { + ErrorReporter.reportError(typeName, message) +} + +internal object ErrorReporter : ApplicationErrorReporter { + internal var crashReporter: CrashReporting? = null + override fun reportError(typeName: String, message: String) { - crashReporter.submitCaughtException(AppServicesErrorReport(typeName, message)) + crashReporter?.submitCaughtException(AppServicesErrorReport(typeName, message)) } override fun reportBreadcrumb(message: String, module: String, line: UInt, column: UInt) { - crashReporter.recordCrashBreadcrumb(Breadcrumb("$module[$line]: $message")) + crashReporter?.recordCrashBreadcrumb(Breadcrumb("$module[$line]: $message")) } } diff --git a/mobile/android/android-components/components/support/remotesettings/build.gradle b/mobile/android/android-components/components/support/remotesettings/build.gradle @@ -26,6 +26,7 @@ android { } dependencies { + implementation project(':components:support-appservices') implementation project(':components:support-base') implementation project(':components:support-ktx') implementation project(':components:support-utils') diff --git a/mobile/android/android-components/components/support/remotesettings/src/main/java/mozilla/components/support/remotesettings/RemoteSettingsClient.kt b/mobile/android/android-components/components/support/remotesettings/src/main/java/mozilla/components/support/remotesettings/RemoteSettingsClient.kt @@ -25,11 +25,13 @@ import mozilla.appservices.remotesettings.RemoteSettingsRecord import mozilla.appservices.remotesettings.RemoteSettingsResponse import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.util.writeString +import mozilla.components.support.rusterrors.reportRustError import org.json.JSONObject import java.io.File import java.io.FileNotFoundException import java.io.IOException import java.net.URL +import mozilla.appservices.remotesettings.InternalException as UniffiInternalException /** * Helper class to download collections from remote settings in app services. @@ -75,6 +77,10 @@ class RemoteSettingsClient( } catch (e: NullPointerException) { Logger.error(e.message.toString()) RemoteSettingsResult.NetworkFailure(e) + } catch (e: UniffiInternalException) { + Logger.error(e.toString()) + reportRustError("remote-settings-internal-error", e.toString()) + RemoteSettingsResult.NetworkFailure(e) } }