Skip to content
Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
images
src
README.md
build.gradle
proguard-rules.pro

README.md

Android Components > Libraries > Crash

A generic crash reporter component that can report crashes to multiple services.

Main features:

  • Support for multiple crash reporting services (included is support for Sentry and Socorro).
  • Support for crashes caused by uncaught exceptions.
  • Support for native code crashes (currently primarily focused on GeckoView crashes).
  • Can optionally prompt the user for confirmation before sending a crash report.
  • Support for showing in-app confirmation UI for non-fatal crashes.

Usage

Setting up the dependency

Use Gradle to download the library from maven.mozilla.org (Setup repository):

implementation "org.mozilla.components:lib-crash:{latest-version}"

Setting up crash reporting

In the onCreate() method of your Application class create a CrashReporter instance and call install():

CrashReporter(
    services = listOf(
        // List the crash reporting services you want to use
    )
).install(this)

With this minimal setup the crash reporting library will capture "uncaught exception" crashes and "native code" crashes and forward them to the configured crash reporting services.

⚠️ Note: To avoid conflicting setups do not use any other crash reporting libraries/services independently from this library.

Sending crash reports to Sentry

⚠️ Note: The crash reporter library is compiled against the Sentry SDK but it doesn't require it as a dependency. The app using the component is responsible for adding the Sentry dependency to its build files in order to use Sentry crash reporting.

Add a SentryService instance to your CrashReporter in order to upload crashes to Sentry:

CrashReporter(
    services = listOf(
        SentryService(applicationContext, "your sentry DSN")
    )
).install(applicationContext)

By default only the DSN is needed. But there are additional option configuration parameters:

SentryService(
	applicationContext,
	"your sentry DSN",

	// Optionally add tags that will be sent with every crash report
	tags = mapOf(
		"build_flavor" to BuildConfig.FLAVOR,
		"build_type" to BuildConfig.BUILD_TYPE
	),
	
	// Send an event to Sentry for every native code crash. Native code crashes 
	// can't be uploaded to Sentry currently. But sending an event to Sentry
	// gives you an idea about how often native code crashes. For sending native
	// crash reports add additional services like Socorro.
	sendEventForNativeCrashes = true
)	

Sending crash reports to Mozilla Socorro

Socorro is the name for the Mozilla Crash Stats project.

⚠️ Note: Socorro filters crashes by "app name". New app names need to be whitelisted for the server to accept the crash. File a bug if you would like to get your app added to the whitelist.

Add a MozillaSocorroService instance to your CrashReporter in order to upload crashes to Socorro:

CrashReporter(
    services = listOf(
		MozillaSocorroService(applicationContext, "your app name"),
    )
).install(applicationContext)

⚠️ Note: Currently only native code crashes get uploaded to Socorro. Socorro has limited support for "uncaught exception" crashes too, but it is recommended to use a more elaborate solution like Sentry for that.

Showing a crash reporter prompt

Optionally the library can show a prompt asking the user for confirmation before sending a crash report.

The behavior can be controlled using the shouldPrompt parameter:

CrashReporter(
    // Always prompt
    shouldPrompt = CrashReporter.Prompt.ALWAYS,
    
    // Or: Only prompt for native crashes
    shouldPrompt = CrashReporter.Prompt.ONLY_NATIVE_CRASH,
    
    // Or: Never show the prompt
    shouldPrompt = CrashReporter.Prompt.NEVER,
    
    // ..
).install(applicationContext)

Customizing the prompt

The crash reporter prompt can be customized by providing a PromptConfiguration object:

CrashReporter(
	promptConfiguration = CrashReporter.PromptConfiguration(
		appName = "My App",
		organizationName = "My Organization",

		// An additional message that will be shown in the prompt
		message = "We are very sorry!"

		// Use a custom theme for the prompt (Extend Theme.Mozac.CrashReporter)
		theme = android.R.style.Theme_Holo_Dialog
	),

	// ..
).install(applicationContext)

Handling non-fatal crashes

A native code crash can be non-fatal. In this situation a child process crashed but the main process (in which the application runs) is not affected. In this situation a crash can be handled more gracefully and instead of using the crash reporter prompt of the component an app may want to show an in-app UI for asking the user for confirmation.

Provide a PendingIntent that will be invoked when a non-fatal crash occurs:

// Launch this activity when a crash occurs.
val pendingIntent = PendingIntent.getActivity(
    context,
    0,
    Intent(this, MyActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    },
    0)

CrashReporter(
    shouldPrompt = CrashReporter.Prompt.ALWAYS,
    services = listOf(
        // ...
    ),
    nonFatalCrashIntent = pendingIntent
).install(this)

In your component that receives the Intent (e.g. Activity) you can use Crash.fromIntent() to receive the Crash object. Once the user has approved sending a report call submitReport() on your CrashReporter instance.

// In your crash handling component (e.g. Activity)
if (Crash.isCrashIntent(intent) {
	val crash = Crash.fromIntent(intent)
	
	...
}	

// Once the user has confirmed sending a crash report:
crashReporter.submitReport(crash)

⚠️ Note: submitReport() may block and perform I/O on the calling thread.

Sending GeckoView crash reports

⚠️ Note: For sending GeckoView crash reports GeckoView 64.0 or higher is required!

Register CrashHandlerService as crash handler for GeckoView:

val settings = GeckoRuntimeSettings.Builder()
    .crashHandler(CrashHandlerService::class.java)
    .build()

// Crashes of this runtime will be forwarded to the crash reporter component
val runtime = GeckoRuntime.create(applicationContext, settings)

// If you are using the browser-engine-gecko component then pass the runtime
// to your code initializing the engine:
val engine = GeckoEngine(applicationContext, defaultSettings, runtime)

ℹ️ You can force a child process crash (non fatal!) using a multi-process (E10S) GeckoView by loading the test URL about:crashcontent. Using a non-multi-process GeckoView you can use about:crashparent to force a fatal crash.

License

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/
You can’t perform that action at this time.