Build apps with Sentry
Sentry crash reporting is wired into every Goodspeed app with null-safe init, breadcrumb helpers, and sensitive-key redaction. Goodspeed generates Sentry as a standard part of every app, so the output is a working codebase from day one, not a scaffold you have to finish yourself.
WHAT GETS GENERATED
Built into every Sentry build
Every app Goodspeed generates with Sentry includes these production-ready patterns, wired together from the first build.
| Item | Description | Strength |
|---|---|---|
| lib/sentry.ts null-safe initialization | Sentry.init only runs when EXPO_PUBLIC_SENTRY_DSN is set and gasConfig.features.analytics.crashReporting is true. Empty DSN makes all exports no-ops. | Reliability |
| sanitizeData sensitive-key redaction | sanitizeData redacts any property key matching a regex of 30+ sensitive patterns (password, token, secret, apiKey, etc.) before the event is sent to Sentry. | Security |
| Breadcrumb helpers for UI, API, auth, navigation | addBreadcrumb(category, message) writes a typed breadcrumb. Callers across lib/posthog.ts, lib/revenuecat.ts, and services/ use it to produce readable event trails. | Debugging |
| User context enrichment | setSentryUser sets scope.user with the subscription tier, app version, and device model after auth. clearSentryUser clears it on sign-out. | Context |
| Transaction and span support | captureTransaction wraps expensive operations (image upload, sync replay) in Sentry transactions for performance monitoring. | Performance |
Source: gas-template repository · Error Monitoring
REAL GENERATED CODE
A snippet from a Sentry app the studio shipped
This pattern comes directly from the gas-template codebase, the foundation every Goodspeed app is generated on. The studio generates Sentry code like this for every app in the pipeline, not just a hello-world scaffold.
Null-safe init + redaction
// lib/sentry.ts: null-safe Sentry init const dsn = process.env.EXPO_PUBLIC_SENTRY_DSN ?? ''; const isEnabled = gasConfig.features.analytics.crashReporting && !!dsn; if (isEnabled) { Sentry.init({ dsn, tracesSampleRate: 0.2 }); } export function sanitizeData(data: Record<string, unknown>) { const SENSITIVE = /password|token|secret|apiKey|authorization/i; return Object.fromEntries( Object.entries(data).map(([k, v]) => [k, SENSITIVE.test(k) ? '[REDACTED]' : v] ) ); }
GDaily Allergens
Today's log
Gluten
Tree nuts
Shellfish
Dairy
HomeScanLogProfile