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

# Crashes and issues

> What Apsio records when an app fails, and how occurrences are grouped into issues.

## What is recorded

| Kind | How it is captured | When it is sent |
| - | - | - |
| Crash | The SDK's crash handler (KSCrash on iOS): signals, Mach exceptions, C++ and Objective-C exceptions | At the next launch |
| Handled error | `recordError` in your code, with the stack where it was called | With the next batch |
| Hang | MetricKit's hang diagnostics, with the main thread's stack | When iOS delivers them, from the next launch |
| Termination without a crash report | Inferred at the next launch: the last session ended in the foreground with no crash, no normal exit, no app or OS update and no debugger | At the next launch |

A terminated app cannot send anything, so a crash and the session it ended are reported at
the next launch, with the release, build and OS of the run that crashed.

Terminations without a crash report are usually the system ending the app: out of memory,
or the watchdog. [Release health](/concepts/sessions) counts them as abnormal exits,
separately from crashes.

## Issues

An issue is a group of occurrences with the same cause. Every kind above becomes issues: an
issue's `kind` is `crash`, `error`, `hang`, `anr` (Android) or `abnormal_exit`, and the
[read API](/read-api#endpoints) filters by it. Each occurrence keeps its session, so an issue
shows the breadcrumbs, logs and requests before each failure. An issue lists:

* its occurrences, and the users and sessions affected;
* when it was first and last seen, and in which releases;
* the devices it affects;
* the stack of its latest occurrence, symbolicated with function, file and line when the
  [symbols](/concepts/symbols) are uploaded, next to the stack as the device sent it.

## Grouping

Apsio computes a fingerprint for each occurrence on the server. Occurrences with the same
fingerprint in the same app are one issue.

| Kind | Fingerprint |
| - | - |
| Crash | The exception type and the top five frames of the crashing thread that are in your app, without line numbers |
| Handled error | The fingerprint you pass to `recordError`, if any; otherwise the error type and the in-app frames where it was recorded, or the message with numbers removed when there is no stack |
| Hang or ANR | The main thread's in-app frames, or one fingerprint per app when the stack is only system code |
| Abnormal exit | The exit reason (for example memory or watchdog) and whether the app was in the foreground or the background |

Line numbers are left out so that an unrelated edit in the same file does not split an issue.
Before symbols arrive, a frame is its binary and offset; when they arrive, the occurrence is
symbolicated again, grouped by function name, and may move to another issue. The issue's id is
its fingerprint.

The grouping rules are versioned: a new version never moves the occurrences you already have.
Each occurrence records how it was grouped, as `grouping` with a `version` and a `reason`:

| Reason | The fingerprint came from |
| - | - |
| `in_app_frames` | Your app's frames, all symbolicated |
| `in_app_addresses` | Your app's frames, some still without symbols |
| `system_frames` | System libraries only, for a crash with no frame in your app |
| `system_only` | Nothing in your app, for a hang or an ANR |
| `exception_type` | The exception type, for a crash without a stack |
| `sdk_fingerprint` | The fingerprint you passed to `recordError` |
| `message` | The error type and message, for an error without frames in your app |
| `exit_reason` | The exit reason, for an abnormal exit |

### Your own fingerprint

For handled errors, a fingerprint you choose replaces the default. Use it to group errors that
come from different places, or to split errors that look alike:

```swift theme={null}
Apsio.recordError(error, fingerprint: "checkout-card-declined")
```

A fingerprint applies to one app. It cannot be set for crashes.

## Missing symbols

When an occurrence arrives before its symbols, `symbolicated` is `false` and
`missing_debug_ids` lists the debug id of every image in its stack without symbols, Apple's
system frameworks included. The images of your own app to upload, per release, come from
`GET /v1/projects/{projectId}/releases/{release}/missing-symbols`. See
[Symbols and dSYMs](/concepts/symbols).


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