> ## Documentation Index
> Fetch the complete documentation index at: https://docs.germainux.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Error and Exception Monitoring for Android App

> Collect errors and exceptions from Android applications with the GermainUX Mobile App library.

Components
[`Engine`](https://docs.germainux.com/main/germain-ux-engine)
[`Mobile App`](https://docs.germainux.com/main/germain-ux-mobile-app)
[`RUM JS`](https://docs.germainux.com/main/germain-ux-rum-js)

Availability
2022.1 or later

> [card] [Error Types](#error-types)
>
> Pick the right error event

> [card] [Report Handled Exceptions](#report-handled-exceptions)
>
> Log meaningful caught exceptions

> [card] [Analyze Errors](#analyze-errors)
>
> Rank errors by user impact

> [card] [Troubleshooting](#troubleshooting)
>
> Fix Android error reporting

## Configure Error, Exception, and Crash Monitoring for Android

## Overview

The GermainUX Mobile App library can collect:

* Crashes caused by unhandled exceptions
* Handled exceptions reported by application code
* Application errors that do not throw an exception
* Selected Android StrictMode violations, when enabled and supported
* Application uptime and closure context associated with a crash

Error data can be correlated with the application version, Android version, device, user session, screen, fragment, transaction, and preceding application events.

## Error Types

Use the appropriate GermainUX event for each condition:

| Type | When to use |
| - | - |
| Crash | The application terminates because of an unhandled failure |
| Handled exception | An exception occurred but the application caught and handled it |
| Application error | A meaningful failure occurred without a Java or Kotlin exception |
| StrictMode violation | Android detected a configured development or runtime policy violation |

Do not report expected user validation, such as a required field left empty, as an application error unless the software itself is failing to operate as intended.

## Automatic Crash Detection

Unhandled-exception monitoring is enabled automatically after GermainUX initialization unless it is explicitly disabled:

```text theme={null}
config.setAutomaticUnhandledExceptionsMonitoring(false);
```

When an unhandled exception terminates the application, GermainUX attempts to capture:

* Exception type
* Error message
* Stack trace
* Crash timestamp
* Application version
* Android and device context

> [accordion] Show all 10
>
> * Active user session
> * Related screen or fragment
> * Application uptime
> * Application-closure event

Delivery is attempted before the application process terminates, but Android does not guarantee enough execution time to transmit crash telemetry immediately.

## Disable Automatic Crash Detection

Disable automatic monitoring only when required, such as when:

* Another crash handler must remain solely responsible for uncaught exceptions.
* The application implements a custom crash-reporting workflow.
* Crash reporting is disabled for a specific build type.
* Consent or privacy requirements prevent automatic collection.

### Java

```text theme={null}
GermainAPMConfiguration config =
    new GermainAPMConfiguration(
        "https://YOUR_GERMAINUX_HOST/ingestion/fact"
    );

config.setAutomaticUnhandledExceptionsMonitoring(false);

GermainAPM.init(this, config);
```

### Kotlin

```text theme={null}
val config = GermainAPMConfiguration(
    "https://YOUR_GERMAINUX_HOST/ingestion/fact"
)

config.setAutomaticUnhandledExceptionsMonitoring(false)

GermainAPM.init(this, config)
```

When multiple crash libraries are installed, verify that their uncaught-exception handlers are compatible and that the original handler chain is preserved.

## Report a Crash Explicitly

Use `collectCrash()` only when the application is treating the condition as a crash or terminal failure.

### Java

```text theme={null}
try {
    runCriticalOperation();
} catch (Throwable error) {
    GermainAPM.collectCrash(
        "CriticalOperationCrash",
        error,
        false
    );

    throw error;
}
```

### Kotlin

```text theme={null}
try {
    runCriticalOperation()
} catch (error: Throwable) {
    GermainAPM.collectCrash(
        "CriticalOperationCrash",
        error,
        false
    )

    throw error
}
```

Parameters:

| Parameter | Description |
| - | - |
| Name | Stable category used to identify the crash |
| Throwable | Exception and stack-trace information |
| StrictMode flag | `true` only when the event represents a StrictMode violation |

`collectCrash()` also records application closure and uptime context. Do not use it for a condition after which the application continues normally. Use `collectException()` or `collectError()` instead.

Avoid catching `Throwable` solely for monitoring in normal application code. The preceding example represents a terminal boundary where the failure is reported and rethrown.

## Report Handled Exceptions

Use `collectException()` inside existing exception-handling logic when the exception is operationally meaningful.

### Basic example

Java:

```text theme={null}
try {
    loadCustomerData();
} catch (IOException error) {
    GermainAPM.collectException(error);

    showCachedData();
}
```

Kotlin:

```text theme={null}
try {
    loadCustomerData()
} catch (error: IOException) {
    GermainAPM.collectException(error)

    showCachedData()
}
```

The application remains responsible for handling the exception. Reporting it to GermainUX does not recover the failed operation or alter the application flow.

### Custom exception name

Use a stable custom name when the default exception class does not provide enough business or technical context.

Java:

```text theme={null}
try {
    submitOrder();
} catch (IOException error) {
    GermainAPM.collectException(
        "OrderSubmissionException",
        error,
        false
    );

    displayRetryOption();
}
```

Kotlin:

```text theme={null}
try {
    submitOrder()
} catch (error: IOException) {
    GermainAPM.collectException(
        "OrderSubmissionException",
        error,
        false
    )

    displayRetryOption()
}
```

The third parameter identifies whether the reported exception represents a StrictMode violation.

Use consistent names rather than including record IDs, user names, timestamps, or dynamic error values in the event name.

## Report Application Errors

Use `collectError()` when an important failure occurs without an exception.

Examples include:

* Invalid response received from a service
* Required application data missing
* Business transaction rejected unexpectedly
* Local data synchronization failed
* Expected result not produced
* Application entered an invalid state

### Java

```text theme={null}
if (!response.isSuccessful()) {
    GermainAPM.collectError(
        "CustomerSyncFailed",
        "The customer synchronization request failed."
    );

    displayRetryOption();
}
```

### Kotlin

```text theme={null}
if (!response.isSuccessful) {
    GermainAPM.collectError(
        "CustomerSyncFailed",
        "The customer synchronization request failed."
    )

    displayRetryOption()
}
```

Keep error content concise and free of sensitive data.

Do not pass:

* Passwords
* Authentication tokens
* Payment information
* Personal or health information
* Full request or response bodies
* Database records
* Secret URLs or query parameters

## StrictMode Violations

Android StrictMode can identify development and runtime policy violations such as:

* Disk reads or writes on monitored threads
* Network operations on the main thread
* Slow calls
* Resource mismatches
* Leaked closable objects
* Leaked activities or registrations

> [accordion] Show all 10
>
> * File URI exposure
> * Cleartext network use
> * Untagged sockets
> * Unsupported non-SDK API usage

The violations available depend on the Android version and the StrictMode policies enabled by the application.

StrictMode findings are not automatically equivalent to production crashes. Some violations log a warning, while others can be configured to terminate the application. Categorize them according to their actual behavior and impact.

Use StrictMode cautiously in production. Validate the selected policies and penalties in a test environment before rollout.

## Categorize Errors in GermainUX

Configure categories that distinguish:

* Application crashes
* Handled exceptions
* Application errors
* StrictMode violations
* User-facing software errors
* Silent software errors

> [accordion] Show all 9
>
> * Expected user validation
> * Network and integration failures
> * Data and synchronization failures

This prevents user validation and low-value diagnostic events from inflating the KPI used for software failures.

## Analyze Errors

Use GermainUX dashboards to analyze errors by:

* Error or exception name
* Exception class
* Application version
* Android version
* Device manufacturer and model
* Screen or fragment

> [accordion] Show all 12
>
> * Transaction
> * User session
> * User or role, when approved
> * First and last occurrence
> * Affected users and sessions
> * Frequency and trend

Prioritize errors based on user impact, recurrence, severity, affected business process, and whether they were introduced by a recent release.

## Alerts

Configure alerts for conditions such as:

* New crash signature
* Increased crash rate
* Critical transaction failure
* Repeated handled exception
* Application-version regression
* Error affecting many users
* Sudden increase in StrictMode violations
* Missing crash data after a known failure

Avoid sending an alert for every individual occurrence of a high-volume error. Use aggregation, minimum affected-user counts, persistence, and severity rules.

## Privacy and Obfuscation

Before enabling error reporting:

* Review exception messages and stack traces for sensitive data.
* Anonymize or exclude sensitive fields.
* Avoid dynamic personal data in exception names.
* Restrict access to diagnostic information.
* Retain R8 or ProGuard mapping files for each release.
* Protect mapping files because they reveal application structure.
* Apply an appropriate retention period.

Obfuscated stack traces may require the corresponding mapping file to identify the original classes and methods.

## Validation

Test the integration in a nonproduction build:

**1. Initialize GermainUX**

**2. Report a controlled application error**

**3. Report a handled exception**

**4. Trigger an unhandled exception in a safe test scenario**

**5. Confirm that the crash is associated with the correct session**

**6. Verify application, version, device, screen, and transaction context**

**7. Confirm that the release build provides usable stack traces**

**8. Verify that sensitive values are excluded**

**9. Test alert thresholds and recipients**

**10. Confirm that another installed crash handler still works, if applicable**

## Troubleshooting

### Unhandled crashes are not collected

Verify that:

* GermainUX initializes before the crash occurs.
* Automatic unhandled-exception monitoring is enabled.
* Another library has not replaced the GermainUX exception handler.
* The device can reach the ingestion endpoint.
* The release build includes the GermainUX library.
* Privacy or processing rules do not discard the event.

A crash that terminates the process immediately may not be transmitted until the library has another opportunity to send retained telemetry, if supported by the installed version.

### Handled exceptions are missing

Confirm that:

* `collectException()` executes.
* The exception is not filtered by configuration.
* The application remains active long enough to distribute telemetry.
* The GermainUX application and environment are enabled.
* The device has network connectivity.

### Stack traces are unreadable

Check:

* R8 or ProGuard configuration
* Preservation of source and line-number attributes
* Mapping-file retention
* Installed library compatibility
* Whether the exception was created without a meaningful stack trace

### Duplicate crashes appear

Verify that:

* The same failure is not reported manually and automatically.
* Multiple crash libraries are not forwarding the same event.
* Retry or retained-event delivery is deduplicated by the configured processing rules.

## Get Help

> [card] [Contact GermainUX Support](https://docs.germainux.com/main/support.md)
>
> The GermainUX team helps you get up and running faster, empower your team, turn data into actionable insights, and optimize performance to deliver measurable business outcomes.

> [card] Can't find what you need?
>
> Search all GermainUX docs with **Ctrl + K**, or use the feedback buttons at the bottom of this page to tell us what is missing.

The content of this document is proprietary to GERMAIN SOFTWARE.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.