Skip to content
TraceItX Docs
Documentation

Crash reporting

Not every bug has a user willing to file it. Uncaught errors become reports on their own.

Updated

Crash reporting is on by default — the payload is data the SDK already holds (the exception plus the breadcrumb trail), fully redacted. It is a client veto:

<TraceItXProvider config={{ apiKey: 'txx_live_…', crashReporting: { disabled: true } }}>

What is caught

mechanismFires on
errorutilsAn uncaught JS error, via React Native’s ErrorUtils handler. Both platforms.
uncaught-exception-handlerA native crash below the bridge — Android only. On iOS a native exception adds an error breadcrumb but does not file a report.

There is no unhandled-rejection handler. A promise rejection nobody handles does not become a report on this SDK; only ErrorUtils is installed on the JS side, and it always reports errorutils.

What happens next depends on whether the process survives. A non-fatal error leaves your app running, so the report uploads immediately. A fatal one — a native crash, or a JS error React Native treats as fatal — kills the process, so the report is written to the outbox and sent on the next launch.

Non-fatal errors are throttled per session, so a render loop does not flood you with reports. Fatal errors always report.

occurredAt vs submittedAt

They differ, and for native crashes they can differ by a lot. Order your triage on occurredAt, not submittedAt, or a crash loop looks like it all happened at once when the user finally reopened the app.

What arrives

{
  "exceptionType": "TypeError",
  "message": "cart.lines is undefined",
  "frames": [
    { "raw": "at Cart (cart.tsx:42:11)" }
  ],
  "mechanism": "errorutils",
  "handled": false,
  "occurredAt": "2026-06-15T11:59:58.400Z",
  "fingerprint": "9f2c1ab30d84e177"
}

Frames are raw — each frame is the stack line as raw, with no parsed file, line or col, and symbolication is not in v1. A release build gives you minified JS frames, so keep your source maps; mapping happens on your side for now.

mechanism is a plain string, not an enum, so v2 can add values without older receivers rejecting reports.

Grouping

fingerprint is 16 hex characters computed on the client from the exception type and the top frames — a heuristic, deliberately, so grouping works with no server round-trip and no symbolication step. Treat it as a strong hint, not an identity.

What comes with it

An unattended report’s title is generated from the exception — TypeError: cart.lines is undefined — and its description is empty, since nobody typed one. What makes it useful is everything else: the breadcrumb trail leading to the throw, the console state, the screen the user was on, and the device and app context. There is no screenshot and no replay — the process may already be gone, and the payload is built from the buffers only.

The JS trail survives a fatal error because breadcrumbs live in the native buffer rather than in your JS context — see Breadcrumbs.