Revision control
Copy as Markdown
# [Android Components](../../../README.md) > 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](https://sentry.io) and [Socorro](https://wiki.mozilla.org/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](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
```Groovy
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()`:
```Kotlin
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.
### Recording crash breadcrumbs to supported services
Using the `CrashReporter` instance to record crash breadcrumbs. These breadcrumbs will then be sent when a crash occurs to aid in debugging. Breadcrumbs are reported only if the underlying crash reporter service supports it.
⚠️ Note: Directly using Sentry's breadcrumb will not work as expected on Android 10 or above. Using the `CrashReporter` breadcrumb is preferred.
```Kotlin
crashReporter.recordCrashBreadcrumb(
CrashBreadcrumb("Settings button clicked", data, "UI", Level.INFO, Type.USER)
)
```
### 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:
```Kotlin
CrashReporter(
services = listOf(
SentryService(applicationContext, "your sentry DSN")
)
).install(applicationContext)
```
By default only the `DSN` is needed. But there are additional option configuration parameters:
```Kotlin
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](https://wiki.mozilla.org/Socorro) is the name for the [Mozilla Crash Stats](https://crash-stats.mozilla.org/) project.
⚠️ Note: Socorro filters crashes by "app name". New app names need to be safelisted for the server to accept the crash. [File a bug](https://bugzilla.mozilla.org/enter_bug.cgi?product=Socorro) if you would like to get your app added to the safelist.
Add a `MozillaSocorroService` instance to your `CrashReporter` in order to upload crashes to Socorro:
```Kotlin
CrashReporter(
services = listOf(
MozillaSocorroService(applicationContext, "your app name")
)
).install(applicationContext)
```
`MozillaSocorroService` will report version information such as App version, Android Component version, Glean version, Application Services version, GeckoView version and Build ID
⚠️ 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.
### Sending crash reports to Glean
[Glean](https://docs.telemetry.mozilla.org/concepts/glean/glean.html) is a new way to collect telemetry by Mozilla.
This will record crash counts as a labeled counter with each label corresponding to a specific type of crash (`fatal_native_code_crash`, `nonfatal_native_code_crash`, `caught_exception`, `uncaught_exception`, currently).
The list of collected metrics is available in the [metrics.yaml file](metrics.yaml), with their documentation [living here](https://dictionary.telemetry.mozilla.org/apps/fenix/pings/crash).
Due to the fact that Glean can only be recorded to in the main process and lib-crash runs in a separate process when it runs to handle the crash,
lib-crash persists the data in a file format and then reads and records the data from the main process when the application is next run since the `GleanCrashReporterService`
constructor is loaded from the main process.
Add a `GleanCrashReporterService` instance to your `CrashReporter` in order to record crashes in Glean:
```Kotlin
CrashReporter(
services = listOf(
GleanCrashReporterService()
)
).install(applicationContext)
```
⚠️ Note: Applications using the `GleanCrashReporterService` are **required** to undergo [Data Collection Review](https://wiki.mozilla.org/Firefox/Data_Collection) for the crash counts that they will be collecting.
### Showing a crash reporter prompt
![](images/crash-dialog.png)
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:
```Kotlin
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:
```Kotlin
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.
![](images/crash-in-app.png)
Provide a `PendingIntent` that will be invoked when a non-fatal crash occurs:
```Kotlin
// 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)
},
PendingIntentUtils.defaultFlags
)
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.
```Kotlin
// 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:
```Kotlin
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