Crash Reporting with GlitchTip

How PhenomApp crash and error reporting works: @sentry/react-native in JS-only mode shipping events to GlitchTip.

Crash Reporting with GlitchTip

Status: LIVE since 2026-06-04 (PhenomApp PR #92). This was previously listed on the roadmap as future work; it is now in production.

Architecture

  • SDK: @sentry/react-native ~7.2.0 (the Expo SDK 54 compatible pin). GlitchTip speaks the Sentry protocol, so the standard SDK is used unchanged.
  • Mode: JS-only. The SDK runs with enableNative: false. The native layer caused a launch crash in build 31, so native crash capture is deliberately disabled. JavaScript errors, unhandled promise rejections, and explicitly captured messages are reported; pure native crashes are not.
  • DSN: configured in app/config/config.prod.ts (SENTRY_DSN). It is a public client key and safe to ship in the binary.
  • Wiring: app/utils/crashReporting.ts initialises the SDK from Config.SENTRY_DSN.

What gets reported

  • JS exceptions and unhandled rejections
  • Camera record errors (explicit capture added in build 36; see Camera Recording Fix)
  • Android telemetry fallback events: when sensor telemetry is unavailable on Android, the app degrades gracefully and logs the condition to GlitchTip rather than crashing

Post-auth gate chain watchdog

After sign-in, the app runs a chain of gates in order: EULA, then first-login language, then onboarding, then display name. Each gate reports deciding, blocking or clear, and every transition leaves a gate <name>: <state> breadcrumb. If any mounted gate is still deciding 20 seconds after the session starts, the app sends a HANDLED event:

post-auth gates unresolved after 20s: eula=clear, language=clear, onboarding=clear, displayName=deciding

How to read it:

  • blocking is never a fault. It means a gate is on screen waiting for the user.
  • deciding means that gate’s own lookup never came back. Start there.
  • The later gates only mount once the earlier ones clear, so a gate the chain holds back unmounts and withdraws its state (breadcrumb gate <name>: withdrawn). Before PhenomApp#877, a withdrawn gate’s stale deciding stayed behind, and every onboarding run raised a false alarm reading onboarding=blocking, displayName=deciding. Treat events of that shape from older builds as noise.

Build-time settings

All iOS EAS profiles set SENTRY_DISABLE_AUTO_UPLOAD and SENTRY_ALLOW_FAILURE so source-map upload never fails a build. Source maps are currently not uploaded; stack traces are symbolicated locally when needed.

Known limitations

  • enableNative: false means native-only crashes (Swift/Kotlin layer) do not reach GlitchTip. The iOS launch-crash class of bugs must still be caught by device testing; see iOS Launch Crash Fixes.
  • Source maps are not uploaded, so release-build JS stack traces are minified in the GlitchTip UI.